| Class | MetaSearch::Method |
| In: |
lib/meta_search/method.rb
|
| Parent: | Object |
MetaSearch can be given access to any class method on your model to extend its search capabilities. The only rule is that the method must return an ActiveRecord::Relation so that MetaSearch can continue to extend the search with other attributes. Conveniently, scopes (formerly "named scopes") do this already.
Consider the following model:
class Company < ActiveRecord::Base
has_many :slackers, :class_name => "Developer", :conditions => {:slacker => true}
scope :backwards_name, lambda {|name| where(:name => name.reverse)}
scope :with_slackers_by_name_and_salary_range,
lambda {|name, low, high|
joins(:slackers).where(:developers => {:name => name, :salary => low..high})
}
end
To allow MetaSearch access to a model method, including a named scope, just use search_methods in the model:
search_methods :backwards_name
This will allow you to add a text field named :backwards_name to your search form, and it will behave as you might expect.
In the case of the second scope, we have multiple parameters to pass in, of different types. We can pass the following to search_methods:
search_methods :with_slackers_by_name_and_salary_range,
:splat_param => true, :type => [:string, :integer, :integer]
MetaSearch needs us to tell it that we don‘t want to keep the array supplied to it as-is, but "splat" it when passing it to the model method. And in this case, ActiveRecord would have been smart enough to handle the typecasting for us, but I wanted to demonstrate how we can tell MetaSearch that a given parameter is of a specific database "column type." This is just a hint MetaSearch uses in the same way it does when casting "Where" params based on the DB column being searched. It‘s also important so that things like dates get handled properly by FormBuilder.
NOTE: If you do supply an array, rather than a single type value, to :type, MetaSearch will enforce that any array supplied for input by your forms has the correct number of elements for your eventual method.
Besides :splat_param and :type, search_methods accept the same :formatter and :validator options that you would use when adding a new MetaSearch::Where:
formatter is the Proc that will do any formatting to the variable passed to your method. The default proc is {|param| param}, which doesn‘t really do anything. If you pass a string, it will be +eval+ed in the context of this Proc.
If your method will do a LIKE search against its parameter, you might want to pass:
:formatter => '"%#{param}%"'
Be sure to single-quote the string, so that variables aren‘t interpolated until later. If in doubt, just use a Proc, like so:
:formatter => Proc.new {|param| "%#{param}%"}
validator is the Proc that will be used to check whether a parameter supplied to the method is valid. If it is not valid, it won‘t be used in the query. The default is {|param| !param.blank?}, so that empty parameters aren‘t added to the search, but you can get more complex if you desire. Validations are run after typecasting, so you can check the class of your parameters, for instance.
| formatter | [R] | |
| name | [R] | |
| type | [R] | |
| validator | [R] |