views:

18

answers:

1

In one particular Railcasts episode Ryan talks about advanced search and in that he uses some code so as to find the conditions for the search. As its working isn't explained I wanted some clarification regarding it.

def products
 @products ||= find_products
end

private

def find_products
 Product.find(:all, :conditions => conditions)
end

def keyword_conditions
["products.name LIKE ?", "%#{keywords}%"] unless keywords.blank?
end

def minimum_price_conditions
 ["products.price >= ?", minimum_price] unless minimum_price.blank?
end

def maximum_price_conditions
 ["products.price <= ?", maximum_price] unless maximum_price.blank?
end

def category_conditions
 ["products.category_id = ?", category_id] unless category_id.blank?
end

def conditions
 [conditions_clauses.join(' AND '), *conditions_options]
end

def conditions_clauses
 conditions_parts.map { |condition| condition.first }
end

def conditions_options
 conditions_parts.map { |condition| condition[1..-1] }.flatten
end

def conditions_parts
 private_methods(false).grep(/_conditions$/).map { |m| send(m) }.compact
end

I would welcome any information as to how this works especially the method products as he even calls it as products.name etc.

A: 

He defines some methods for the conditions in his search form: keyword_conditions, minimum_price_conditions ans so on. products.name means the field name from the table products.

The method

def conditions_parts
  private_methods(false).grep(/_conditions$/).map { |m| send(m) }.compact
end

uses reflection to look at the private methods of this class which have the name that ends with _conditions (The regex /_conditions$/) and joins only those that don't return null (compact)

The method

def conditions
  [conditions_clauses.join(' AND '), *conditions_options]
end

adds a AND keyword between the conditions and passes the result to Product.find which makes the SQL query and returns the result set.

True Soft
Wow thanks, that was very helpful. However i have a small doubt as in the category_id is the id for the category model right. SO shouldn't there be something like searches beongs_to :category ?
Prateek
No, because searches do not belong to a category; and `category_id` can be blank for a search.
True Soft