2012-04-24 6 views
0

私はモデルカテゴリを持っています。これはhas_many Products、製品はhas_many Categoriesです。ユーザーがカテゴリを検索すると、Arelオブジェクトを失うことなく、一致するカテゴリの商品を返したいと思います。ここで私がこれまで持っているものです。Railsの "where"クエリで関連オブジェクトだけを選択するにはどうすればいいですか?

Category.where("upper(title) like ?", search_term.upcase).map {|category| category.products}.flatten 

これは、製品を返すのトリックを行いますが、もちろん私が持っているものではないアレイとARELです。私は:includes(:products)句を追加するまで得ることができるので、私は本当に戻って製品を得るが、私はまだそれらのカテゴリに添付している。私が返すのは、製品にのみアドレスするArelであるようにクエリを調整するにはどうすればよいですか?

答えて

3

あなたが探している製品であれば、検索するときにはProductオブジェクトで始めるべきでしょう。たとえば、あなたはこのようにそれを行うことができます:

Product.joins(:categories).where("upper(categories.title) like ?", search_term.upcase) 

を私はjoinsの代わりincludesを使用する理由は、それはINNER JOINを代わりにLEFT OUTERのあなただけされている製品を返却するために必要なものであるJOINを実行します参加しています見つかったカテゴリに実際に関連付けられています。あなたはこのようなあなたの製品モデルの範囲内でのすべてを包むことができ、それは少しよりエレガントにするには

# In Product.rb 
scope :in_categories_like, Proc.new{ |search_term| 
    joins(:categories).where("upper(categories.title) like ?", search_term.upcase) 
} 

# In use 
@products = Product.in_categories_like(params[:search_term]) 
+1

[「クラスメソッドを使用すると、スコープの引数を受け入れるための好ましい方法です」] (http://guides.rubyonrails.org/active_record_querying.html#passing-in-arguments)でも、それは主にニトピッキングです。 –

+0

ありがとう、それは良い点です。 – DanneManne

+0

ちょうど記録のために: 'def self.in_categories_like(search_term); joins(:categories).where( "upper(categories.title)like?"、search_term.upcase);終わり。 –

関連する問題