Hi all,
So far as I know, while using acts_as_ferret, we should add the
following declaration in the ActiveRecord model which is going to be
indexed:
acts_as_ferret({:fields => @@ferrect_fields})
in which @@ferrect_fields is a hash containing all the field to be
indexed. This is pretty much for some simple situations. But I got a
more complex situation that I want to define the fields to be indexed
for every instance of the same model.
My requirements are something like this:
Suppose we have a model “Product”, in “Product” I’ve declared a
polymorphic relationship with model “Property1” and “Property2”, the
following code will show this:
class Product < ActiveRecord::Base
belongs_to :property, :polymorphic => true
@@ferret_fields = {…}
acts_as_ferret({:fields => @@ferret_fields})
end
class Property1 < ActiveRecord::Base
has_one :product, :as => :property
end
class Property2 < ActiveRecord::Base
has_one :product, :as => :property
end
Now I want to provide full text search capability for “Product” and it’s
obvious that “Product” should contains its “property” while being
indexed. So I should define “ferret_fields” class method in “Property1”
and “Property2” to collect all their fields and dynamically define the
corresponding method in “Product”. The code is something like this:
class Property1 < ActiveRecord::Base
has_one :product, :as => :property
def self.ferret_fields
# return a hash containing all the fields to be indexed in aaf’s
format
end
end
class Property2 < ActiveRecord::Base
has_one :product, :as => :property
def self.ferret_fields
# return a hash containing all the fields to be indexed in aaf’s
format
end
end
class Product < ActiveRecord::Base
belongs_to :property, :polymorphic => true
@@ferret_fields = {…}
@@ferret_fields.merge!(Property1.ferret_fields)
@@ferret_fields.merge!(Property2.ferret_fields)
acts_as_ferret({:fields => @@ferret_fields})
Property1.ferret_fields.keys.each do |field|
define_method("#{field}") do
result = property.send("#{field}")
end
end
Property2.ferret_fields.keys.each do |field|
define_method("#{field}") do
result = property.send("#{field}")
end
end
end
But there are two problems in the above code:
- If the property object in a product object is “Property1”,
property.send("#{field}") in “Property2”'s block will cause a method
missing error, vice versa. - Say “Property1” has 500 fields as well as “Property2”, each product
will be indexed using 1000 fields while only at most 500 fields contains
value.
How can I solve these problems and meet my requirements? Any ideas about
this?