Form Filters
When using a data_method
, you can add form filters by specifying ui_filters
in the YAML and passing a block to render_report
, as shown in the example below.
If you use a multi_autocomplete
filter in the view, you'll need to define the autocomplete_method
for that filter in the ui_filters
hash, as shown below.
To learn more about using form filters, see Form Filters.
To create the chart above, simply add the following YAML file and call render_report
in any view:
YAML
config/reports_kit/reports/data_methods_form_filters.yml
data_method: MyDataMethods.posts_by_author_with_filters ui_filters: - key: author autocomplete_method: MyAutocompleteMethods.author - created_at - is_featured - title chart: options: legend: display: false scales: xAxes: - scaleLabel: display: true labelString: Author yAxes: - scaleLabel: display: true labelString: Posts ticks: beginAtZero: true
Note: The "chart.options" option is passed to Chart.js, so any values supported by Chart.js are supported here, too.
View
app/views/my_controller/my_view.html.haml
= render_report 'data_methods_form_filters' do |report| = report.form do |f| .pull-right = f.date_range :created_at = f.multi_autocomplete :author, placeholder: 'Author...' = f.string_filter :title, placeholder: 'Title (e.g. The)...', style: 'width: 175px;' .checkbox = label_tag :is_featured do = f.check_box :is_featured Featured
Data Methods
app/services/my_data_methods.rb
class MyDataMethods # { 'Bernice' => 191, 'Carlee' => 160, 'Edison' => 60, ... } def self.posts_by_author(properties) Post.joins(:author).group('authors.name').order('authors.name').count end # [ # [["Jul 3, 2016", "Hilton"], 2], # [["Jul 10, 2016", "Hilton"], 2], # ... # [["Jul 3, 2016", "Carlee"], 3], # [["Jul 10, 2016", "Carlee"], 5], # ... # ] def self.posts_by_created_at_week_and_author(properties) # The `group_by_week` method is provided by the `groupdate` gem. Post.joins(:author).group_by_week('posts.created_at').group('authors.name').count.map do |(date, author_name), count| [[date.strftime('%b %-d, %Y'), author_name], count] end end # { 'Bernice' => 191, 'Carlee' => 160, 'Edison' => 60, ... } def self.posts_by_author_with_filters(properties) ui_filters = properties[:ui_filters] posts = Post.joins(:author).group('authors.name').order('authors.name') posts = posts.where(created_at: ReportsKit.parse_date_range(ui_filters[:created_at])) if ui_filters[:created_at].present? posts = posts.where(is_featured: true) if ui_filters[:is_featured] posts = posts.where(author_id: ui_filters[:author]) if ui_filters[:author].present? posts = posts.where('title ILIKE ?', "%#{ui_filters[:title]}%") if ui_filters[:title].present? posts.count end end
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