Ruby on Rails:根据几种关系和条件过滤关联

时间:2013-04-08 14:19:21

标签: ruby-on-rails ruby activerecord associations

在我的应用程序中,我有模型Category,Item,Property和PropertyValuation。这个想法是一个类别包含项目,一个项目有几个属性。 PropertyValuation的目的是存储特定项的属性值。模型定义如上:

class Category < ActiveRecord::Base
  attr_accessible :name, :description, :parent, :children, :items, :parent_id

  has_many :children, :class_name => "Category", :foreign_key => "parent_id", :dependent => :nullify
  belongs_to :parent, :class_name => "Category"

  has_many :categorizations
  has_many :items, :through => :categorizations
end

class Item < ActiveRecord::Base
  attr_accessible :name, :description, :property_valuations, :barcode

  has_many :property_valuations, :dependent => :destroy  
  has_many :properties, :through => :property_valuations 

  has_many :categorizations
  has_many :categories, :through => :categorizations

end

class Property < ActiveRecord::Base
  attr_accessible :name, :description, :value_type, :unit, :unit_id

  has_many :property_valuations, :dependent => :destroy  
  has_many :items, :through => :property_valuations
  has_many :property_ranges, :dependent => :destroy

  belongs_to :unit
end

class PropertyValuation < ActiveRecord::Base     
  attr_accessible :property, :item, :value, :categorization

  belongs_to :property
  belongs_to :item
end

现在我的问题是,我已成功设法按名称过滤类别项:

@category.items.where("lower(items.name) like ?", "%#{params[:keywords].downcase}%")

但现在我还想根据相关的属性值过滤这些项目。我收到属性ID和每个属性的值(确切值,最小值或最大值),并且想法是动态构建查询。鉴于我的模型,我该如何做到这一点:例如:我想要名称中包含“foo”的项目,其中id = 1的属性值为2,id = 2的属性值为&lt; 10,id为8的属性值> 2且值<5。

1 个答案:

答案 0 :(得分:0)

您可以将搜索结果从PropertyValuation模型中移除,然后将其加入产品和类别模型

valuations = PropertyValuation.joins(:item)
                              .where(value: 2, property_id: 1)
                              .where('lower(items.name) LIKE ?', "%#{params[keywords].downcase}%")
items      = valuations.map(&:item)

有一个宝石使这个东西变得更容易,一个是Ransack https://github.com/ernie/ransack

Item.search(name_contains:                   params[:keywords], 
            product_valuations_value_equals: 2, 
            product_valuations_property_id:  1)