Rails:使用另一个对象过滤对象列表(has_many through)

时间:2015-09-02 01:22:26

标签: ruby-on-rails rails-activerecord

我有一个对象通过bridge-object ContactSector联系has_many扇区。我在联系人索引页面上有一个表单,我目前通过简单的字符串过滤联系人列表。

我想有一个扇区的复选框列表,而@contacts只返回所选扇区的联系人列表。它不必匹配所有这些,至少一个。

模型

def tryGet[T](jsonObject: JSONObject, name: String): Option[T] = {
    Try(jsonObject.get(name))
      .filter(!JSONObject.NULL.equals(_))
      .map(_.asInstanceOf[T])
      .toOption
}

filterable.rb

class Contact < ActiveRecord::Base
  include Filterable

  scope :firstname, -> (firstname) { where("firstname like ?", "#{firstname}%")}
  scope :lastname, -> (lastname) { where("lastname like ?", "#{lastname}%")}
  scope :title, -> (title) { where("title like ?", "#{title}%")}
  scope :sectors, -> (sector) {where("sector like ?", "#{sector}%")} #Attempt

  has_many :sectors, through: :contact_sectors
  has_many :contact_sectors

  accepts_nested_attributes_for :sectors
end

class ContactSector < ActiveRecord::Base
  belongs_to :contact
  belongs_to :sector
end

class Sector < ActiveRecord::Base
  has_many :contacts, :through => :contact_sectors
  has_many :contact_sectors
end

查看

module Filterable
  extend ActiveSupport::Concern

  module ClassMethods
    def filter(filtering_params)
      results = self.where(nil)
      filtering_params.each do |key, value|
        results = results.public_send(key, value) if value.present?
      end
      results
    end
  end
end

控制器

<%= form_tag '', :method => :get do %>
    <label>Sectors</label><br>
    <% Sector.all.each do |sector| %>
        <%= hidden_field_tag 'sector_ids[]', '' %>
        <%= check_box_tag 'sector_ids[]', sector.id %>
        <%= sector.sector %>
    <% end %>
<% end %>

1 个答案:

答案 0 :(得分:0)

<强>模型

y == 2

查看

class Sector < ActiveRecord::Base
    has_many :contacts, :through => :contact_sectors
    has_many :contact_sectors
    def name_with_initial
        "#{sector}"
    end
end

<强>控制器

<%= collection_check_boxes(:sector, :ids, Sector.all, :id, :name_with_initial) do |b| %>
    <%= b.label do %>
        <%= b.check_box %>
        <%= b.text %>
    <% end %>
<% end %>

我使用各种类别的列表进行多种排序,因此我使用提供的字符串数组来迭代过滤器:

def index
    @contacts = Contact.filter(params.slice(:firstname) #Or just Contact.all
    @filter = params[:sector][:ids]
    @filter.shift #First array entry is always a blank string
    unless @filter.to_a.empty?
        @contacts = @contacts.includes(:sectors).references(:sectors).where('sectors.id IN (?)', @filter)
    end
end

然后像这样使用

  def filtercontacts(filters)
    filters.each {
        |x|
      if eval('params[:' + x + ']')!=nil
        @filter = eval('params[:'+ x +'][:ids]')
        @filter.shift
      end
      unless @filter.to_a.empty?
        @contacts = @contacts.includes(eval(':'+x.pluralize)).references(eval(':'+x.pluralize)).where(eval('\''+ x.pluralize+'.id IN (?)\''), @filter)
        @filter = []
      end
    }
    @contacts
  end