Reputation: 3678
I am trying to use the ransack gem to filter results based on the association count:
For instance each class has 50 students, so i would like to filter to classes with 20 students only.
<%= search_form_for @q do |f| %>
<%= f.text_field :name_cont %>
<%= f.text_field :children_count_lt %>
<%= f.submit 'Filter' %>
<% end %>
@q = Company.ransack(params[:q])
@companies = @q.result.paginate(:page => params[:page], :per_page => 60)
how can i do that.
Upvotes: 1
Views: 2876
Reputation: 21795
Is better to add counter cache, not only simplifies code, it also helps performance(relative), and then you only have to use ransack:
Company.search(params[:q])
No need to change anything in controller. Just model changes to add counter cache:
class Company < ActiveRecord::Base
has_many :children
end
class Child < ActiveRecord::Base
belongs_to :company, counter_cache: true
end
Upvotes: 0
Reputation: 6834
I don't know that Ransack can handle that kind of condition. But you could still have the condition applied along with the other Ransack predicates in your search form with something like this...
Define a class method in the model to filter by child record count:
def self.children_count_lt(count)
return Company.all if count.blank?
Company.includes(:students).group('companies.id').having("COUNT(students.id) < #{count.to_i}").references(:students)
end
Include a number_field_tag
in the search_form_for
in the view:
<%= number_field_tag :children_count_lt, params[:children_count_lt] %>
Call ransack
through the filter in the controller:
@q = Company.children_count_lt(params[:children_count_lt]).ransack(params[:q])
Upvotes: 2