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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With