2012-06-07 34 views
0

我有三个型号,我想执行跨一个简单的搜索:Rails 3.1 - 简单搜索三个(或更多)模型?

class Release < ActiveRecord::Base 
    has_many :artist_releases 
    has_many :artists, :through => :artist_releases 
    has_many :products, :dependent => :destroy  
end 

class Product < ActiveRecord::Base 
    belongs_to :release 
    has_many :artists, :through => :releases   
end 

class Artist < ActiveRecord::Base 
    has_many :artist_releases 
    has_many :releases, :through => :artist_releases 
end 

在我的产品控制器我可以成功地呈现产品列表使用跨越释放和产品搜索:

@products = Product.find(:all, :joins => :release, :conditions => ['products.cat_no LIKE ? OR releases.title LIKE ?', "%#{params[:search]}%","%#{params[:search]}%"]) 

我真的需要能够搜索艺术家。我会怎么做呢?我最好在产品控制器中使用它,因为它是我需要显示的产品列表。

我试过添加:连接=>:艺术家及其变体,但似乎没有工作。

我知道有像斯芬克斯这样的全面搜索选项,但现在我只需要这个简单的方法来工作。

在此先感谢!

回答

1

如果你只是想回来的产品,只需添加两个连接:

@products = Product.joins(:release,:artists).where('products.cat_no LIKE :term OR releases.title LIKE :term OR artists.name LIKE :term', :term => "%#{params[:search]}%").all 

您可能还需要GROUP_BY得到不同的产品回来。

如果您想要多态结果,请尝试3个单独的查询。

+0

这看起来不错,正是我所需要的,但是,它给了我一个错误:ProductsController中的HasManyThroughAssociationNotFoundError - 找不到关联:产品模型中的关联:我知道这不是一个有很多通过,所以我们如何做到这一点期望一对多的关系? – Raoot

+0

请注意连接关联名称中单数':release',而表名中的复数'releases.title'。 Crucial :) –

+0

是的,我喜欢它。正如我测试我删除了所有引用释放和错误总是相同的!?! – Raoot

0

我知道我建议一个简单的方法(可能不是最有效的),但它会得到你的工作做好:

我会创造你的产品型号与此类似的方法:

def find_products_and_artists 
    results = [] 
    Product.find(:all, :conditions => ['products.cat_no LIKE ?', "%#{params[:search]}%"]).each do |prod| 
    results << prod 
    end 
    Release.find(:all, :conditions => ['releases.title LIKE ?', "%#{params[:search]}%"]).each do |rel| 
    results << rel 
    end 
    Artist.find(:all, :conditions => ['artist.name LIKE ?', "%#{params[:search]}%"]).each do |art| 
    results << art 
    end 
    return results 
end 

然后当你调用它的方法和返回的结果存储在一个变量(例如results),你可以查阅一下对象中的每个元素是做

results[i].class 

并且可以使您的代码相应地针对每个对象进行操作。


希望我帮了忙。

+0

谢谢我认为Viktor的答案更接近我的想法,但是这给了我一个错误,所以我会看看我是否可以让你的建议工作。非常感谢 – Raoot