问题
I'm adding pg_search into a Rails app. 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.
回答1:
It is impossible to search associated records with multisearch, due to how polymorphic associations work in Rails and SQL.
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.
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:
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.
来源:https://stackoverflow.com/questions/10512945/how-to-configure-a-pg-search-multisearch-on-associated-models-in-rails