如何在Rails中的关联模型上配置pg_search multisearch?

And*_*vey 8 ruby-on-rails pg-search

我正在将pg_search添加到Rails应用程序中.我并不完全理解这种配置,并希望在正确的方向上轻轻推动.

首先,我已经在我的应用程序上或多或少地设置并运行了多模型站点.但我想扩展它以搜索相关模型.

例如,我有制造商,汽车,模型类.目前,如果我搜索"福特",则只返回制造商.我还想返回所有相关的汽车(属于制造商)和模型(属于汽车).

我可以看到如何做一个范围搜索

class Car
  pg_search_scope :manufactured_by, :associated_against => {
    :manufacturer => [:name]
  }
end
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试在多元素上执行此操作,则无效

class Car
  include PgSearch
  multisearchable :against => [:name], 
    :associated_against => {
        :manufacturer => [:name]
      }
end
Run Code Online (Sandbox Code Playgroud)

它不会产生错误,它根本不会获取相关记录.

我有一种感觉,我错过了一些基本的东西,我理解这一切是如何组合在一起的.如果有人能帮助我理解这一点,或者指出一个良好的信息来源,我真的很感激.我已经浏览了github和相关Railscast的信息,但我仍然遗漏了一些东西.

Gra*_*ins 13

由于多态关联在Rails和SQL中的工作方式,因此无法使用multisearch搜索关联记录.

我将添加一个错误来解释这种情况,以便将来不会让人感到困惑.

对困惑感到抱歉.

你可以做的是在Car上定义一个方法,它返回你想要搜索的文本.

class Car < ActiveRecord::Base
  include PgSearch
  multisearchable :against => [:name, manufacturer_name]
  belongs_to :manufacturer

  def manufacturer_name
    manufacturer.name
  end
end
Run Code Online (Sandbox Code Playgroud)

或者更简洁,你可以委托:

class Car < ActiveRecord::Base
  include PgSearch
  multisearchable :against => [:name, manufacturer_name]
  belongs_to :manufacturer
  delegate :name, :to => :manufacturer, :prefix => true
end
Run Code Online (Sandbox Code Playgroud)

但是,如果您更改了Manufacturer实例的名称,则必须确保pg_search_documents表得到更新,因此您应该添加:touch => true到其关联:

class Manufacturer < ActiveRecord::Base
  has_many :cars, :touch => true
end
Run Code Online (Sandbox Code Playgroud)

这样,当制造商更新时,它将调用所有Car记录上的Active Record回调,这将触发pg_search回调以更新存储在相应pg_search_documents条目中的可搜索文本.

  • 根据 [docs for has_many](http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html),`:touch` 不是一个选项。您需要编写自己的解决方案。此外,我认为您通常不想走另一条路,因为您会在更多记录上调用 touch 并且它可能会开始逃跑,特别是如果这些记录在保存后也接触到其他记录。相反,您可以设置一个 after_save 挂钩来检查特定列是否已更改,使用 find_each 遍历 has_many,并在每条记录上调用 update_pg_search_document (2认同)