1

私の ROR アプリには、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}%")

しかし、関連するプロパティ値に応じて、これらのアイテムをフィルター処理したいと考えています。例: 名前に「foo」が含まれ、プロパティ「A」の値が 1、プロパティ B の値が 2 などのカテゴリ項目が必要です。このようなクエリを実装するにはどうすればよいですか?

4

3 に答える 3

2

テーブルを結合してから、基準に基づいて制限する必要があります。

# Category items by name
Category.joins(:items).where(:items => { :name => keywords })

http://guides.rubyonrails.org/active_record_querying.html#joining-tablesと呼び出しが役立つ場合があり.to_sqlます。

于 2013-04-08T14:25:17.120 に答える
0

を含む ActiveRecord スコープを連鎖させることができますwhere。したがって、最初に名前whereを制限してから、結果を制限するために追加を連鎖させることができます。以下の例では、質問で述べたように、プロパティ「A」の値が 1 の結果を制限します。

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

スコープを変数に格納することもできます。たとえば、同じデータセットをプロパティ A と B で別々に制限したい場合は、次のようにします。

keywords = params[:keywords].downcase
matched_by_name = @category.items.where("lower(items.name) like ?", "%#{keywords}%")
foo = matches_by_name.where(:A => 1)
bar = matches_by_name.where(:B => 1)
于 2013-04-07T16:41:25.113 に答える