简体   繁体   English

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

[英]How to configure a pg_search multisearch on associated models in Rails?

I'm adding pg_search into a Rails app. 我正在将pg_search添加到Rails应用程序中。 I'm not completely understanding the configuration, and would appreciate a gentle nudge in the right direction. 我并不完全理解这种配置,并希望在正确的方向上轻轻推动。

First, I already have a multi model site more or less set up and running on my app. 首先,我已经在我的应用程序上或多或少地设置并运行了多模型站点。 But I want to extend it to also search on associated models. 但我想扩展它以搜索相关模型。

For example, I have Manufacturer, Car, Model classes. 例如,我有制造商,汽车,模型类。 Currently if I search for "Ford", only the manufacturer is returned. 目前,如果我搜索“福特”,则只返回制造商。 I'd also like to return all the associated Cars (which belong to Manufacturer) and Models (which belong to Car). 我还想返回所有相关的汽车(属于制造商)和模型(属于汽车)。

I can see how to do this as a scoped search 我可以看到如何做一个范围搜索

class Car
  pg_search_scope :manufactured_by, :associated_against => {
    :manufacturer => [:name]
  }
end

But if I try to do this on a multisearch it doesn't work 但是,如果我尝试在多元素上执行此操作,则无效

class Car
  include PgSearch
  multisearchable :against => [:name], 
    :associated_against => {
        :manufacturer => [:name]
      }
end

It doesn't generate an error, it simply doesn't pick up the associated records. 它不会产生错误,它根本不会获取相关记录。

I have a feeling I'm missing something fundamental in my understanding of how this all fits together. 我有一种感觉,我错过了一些基本的东西,我理解这一切是如何组合在一起的。 I'd really appreciate if someone could help me understand this, or point me towards a good source of info. 如果有人能帮助我理解这一点,或者指出一个良好的信息来源,我真的很感激。 I've been through the info on github and the related Railscast, but I'm still missing something. 我已经浏览了github和相关Railscast的信息,但我仍然遗漏了一些东西。

It is impossible to search associated records with multisearch, due to how polymorphic associations work in Rails and SQL. 由于多态关联在Rails和SQL中的工作方式,因此无法使用multisearch搜索关联记录。

I will add an error that explains the situation so that in the future it won't be as confusing. 我将添加一个错误来解释这种情况,以便将来不会让人感到困惑。

Sorry for the confusion. 对困惑感到抱歉。

What you could do instead is define a method on Car that returns the text you wish to search against. 你可以做的是在Car上定义一个方法,它返回你想要搜索的文本。

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

  def manufacturer_name
    manufacturer.name
  end
end

Or to be even more succinct, you could delegate: 或者更简洁,你可以委托:

class Car < ActiveRecord::Base
  include PgSearch
  multisearchable :against => [:name, manufacturer_name]
  belongs_to :manufacturer
  delegate :name, :to => :manufacturer, :prefix => true
end

But you have to make sure the pg_search_documents table gets updated if you ever make a name change to a Manufacturer instance, so you should add :touch => true to its association: 但是,如果您更改了Manufacturer实例的名称,则必须确保pg_search_documents表得到更新,因此您应该在其关联中添加:touch => true

class Manufacturer < ActiveRecord::Base
  has_many :cars, :touch => true
end

This way it will call the Active Record callbacks on all the Car records when the Manufacturer is updated, which will trigger the pg_search callback to update the searchable text stored in the corresponding pg_search_documents entry. 这样,当制造商更新时,它将调用所有Car记录上的Active Record回调,这将触发pg_search回调以更新存储在相应pg_search_documents条目中的可搜索文本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM