Use in Multi-Autocompletes

Contextual filters can optionally be used in multi-autocompletes. For example, if you have a multi-autocomplete that lists authors, and you'd like to only show a certain set of authors in the autocomplete's results, you can use a contextual filter to do this.

First, define a for_author contextual filter in the Author model:

# app/models/author.rb

class Author < ApplicationRecord
  include ReportsKit::Model
  reports_kit do
    contextual_filter :for_author, ->(relation, context_params) { relation.where(id: context_params[:author_id]) }
  end
end

Then add the for_author contextual filter to the author filter in the YAML:

measure: post
filters:
- key: author
  contextual_filters:
  - for_author
dimensions:
- created_at

Now, in the view, you can specify the context_params that will be passed to this contextual filter. If you wanted to, say, only show authors with names starting with the letters A-E, you could do the following:

= render_report 'my_report', context_params: { author_id: Author.where("name < 'F'").pluck(:id) } }

N.B. The context_params will be passed from the client to the server when the report's data is generated. If you need to do server-side validation of them, you can do so using context params validation.


To create the chart above, simply add the following YAML file and call render_report in any view:

YAML

config/reports_kit/reports/contextual_filters_in_multi_autocompletes.yml

measure: post
filters:
- key: author
  contextual_filters:
  - for_author
dimensions:
- created_at

View

app/views/my_controller/my_view.html.haml

= render_report 'contextual_filters_in_multi_autocompletes', context_params: { author_id: Author.where("name < 'F'").pluck(:id) } do |report|
  = report.form do |f|
    = f.multi_autocomplete :author, placeholder: 'Author...'

Model

app/models/post.rb

class Post < ApplicationRecord
  belongs_to :author
  has_many :post_views, dependent: :destroy
  has_many :posts_tags, dependent: :destroy
  has_many :tags, through: :posts_tags

  include ReportsKit::Model
  reports_kit do
    aggregation :average_time_to_publish, [:average, 'posts.published_at - posts.created_at']
    contextual_filter :for_author, ->(relation, context_params) { relation.where(author_id: context_params[:author_id]) }
    dimension :approximate_views_count, group: 'ROUND(posts.views_count, -1)'
    filter :is_published, :boolean, conditions: ->(relation) { relation.where(status: 'published') }
  end

  STATUSES = %w(draft private published).freeze

  def to_s
    title
  end
end

Model's Columns

id              integer
author_id       integer
title           string
status          string
published_at    datetime
is_featured     boolean
views_count     integer
created_at      datetime
updated_at      datetime