【问题标题】:Rails using Ransack gem to filter results based on association countRails 使用 Ransack gem 根据关联计数过滤结果
【发布时间】:2013-10-03 12:16:18
【问题描述】:

我正在尝试使用 ransack gem 根据关联计数过滤结果:

例如每个班级有 50 名学生,所以我想过滤到只有 20 名学生的班级。

<%= 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)

我该怎么做。

【问题讨论】:

    标签: ruby-on-rails-4 ransack


    【解决方案1】:

    我不知道 Ransack 可以处理这种情况。但是您仍然可以将条件与搜索表单中的其他 Ransack 谓词一起应用,如下所示...

    在模型中定义一个类方法以按子记录计数过滤:

    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
    

    在视图中的search_form_for 中包含number_field_tag

     <%= number_field_tag :children_count_lt, params[:children_count_lt] %>
    

    通过控制器中的过滤器调用ransack

    @q = Company.children_count_lt(params[:children_count_lt]).ransack(params[:q])
    

    【讨论】:

      【解决方案2】:

      最好加counter cache,不仅简化代码,还有助于性能(相对),然后你只需要使用ransack:

      Company.search(params[:q])
      

      无需更改控制器中的任何内容。只需更改模型以添加计数器缓存:

      class Company < ActiveRecord::Base
        has_many :children
      end
      
      class Child < ActiveRecord::Base
        belongs_to :company, counter_cache: true
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多