0

モデルCategoryにはhas_manyProductsがあり、Productにはhas_manyCategoriesがあります。ユーザーがカテゴリを検索したときに、Arelオブジェクトを失うことなく、一致するカテゴリの製品を返したいのですが。これが私がこれまでに持っているものです:

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

これは製品を返品するトリックを行いますが、もちろん私が持っているのは配列であり、Arelではありません。私は条項を追加することまでできる:includes(:products)ので、確かに製品を取り戻しますが、それでもそれらをそれらのカテゴリーに添付しています。クエリを調整して、製品のみを対象とするArelだけが返されるようにするにはどうすればよいですか?

4

1 に答える 1

4

必要な製品である場合は、検索するときにProductオブジェクトから始める必要があります。たとえば、次のように実行できます。

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

joins代わりに使用する理由includesは、結合がLEFT OUTERJOINではなくINNERJOINを実行するためです。これは、見つかったカテゴリに実際に関連付けられている製品のみを返すために必要なものです。

もう少しエレガントにするために、次のように製品モデルのスコープにすべてをまとめることができます。

# 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])
于 2012-04-24T02:23:07.730 に答える