构造一个has-and-belongs-to-many-many查询

时间:2010-01-12 20:05:09

标签: sql ruby-on-rails

我有一个rails应用程序(在2.2.2版本上运行),它有一个名为Product的模型。产品与功能有着属于多对的关系。问题是我需要为产品提供搜索功能。所以我需要能够搜索具有相似名称和其他一些属性的产品。棘手的部分是搜索还必须返回具有搜索表单中指示的确切功能集的产品(这由一堆复选框表示)。下面的代码可以工作,但它让我觉得效率很低:

@products = Product.find(:all, :conditions=>["home=? AND name LIKE ? AND made_by LIKE ? AND supplier LIKE ? AND ins LIKE ?",hme,'%'+opts[0]+'%','%'+opts[1]+'%','%'+opts[3]+'%','%'+opts[4]+'%'])


#see if any of these products have the correct features
if !params[:feature_ids].nil?
  f = params[:feature_ids].collect{|i| i.to_i}
  @products.delete_if {|x| x.feature_ids!=f}
end

对不起,我对rails / sql的掌握太弱了,但有没有人对如何改进上面的代码有任何建议?非常感谢!

1 个答案:

答案 0 :(得分:1)

首先,我建议您手动编写FeatureProduct模型(而不是使用默认的'has_and_belongs_to_many') EG

class FeatureProduct
  belongs_to :feature
  belongs_to :product
end

class Product
  has_many :feature_products
  has_many :features, :through => :feature_products
end

class Feature
  has_many :feature_products
  has_many :products, :through => :feature_products
end

对于搜索:您可能会发现gem SearchLogic正是您所需要的。它支持'LIKE'条件(这意味着你可以用更多的'Rails方式'来编写你的查询)。它还支持在相关模型上执行条件搜索(在特征模型上更准确)。

解决方案如下:

search = Product.search
search.name_like = opt[0]
search.made_by_like = opt[1]
...
search.feature_products_id_equals = your_feature_ids
..
@product_list = search.all

还有一个excellent screencast解释了这个宝石的使用。

祝你好运:)