#111 Advanced Search Form
May 26, 2008 | 7 minutes | Active Record, Search
If you need to create an advanced search with a lot of fields, it may not be ideal to use a GET request as I showed in episode 37. In this episode I will show you how to handle this by creating a Search resource.
There is a newer version of this episode, see the revised episode.
Resources
views/searches/new.html.erb
<% form_for @search do |f| %>
<p>
<%= f.label :keywords %><br />
<%= f.text_field :keywords %>
</p>
<p>
<%= f.label :category_id %><br />
<%= f.collection_select :category_id, Category.all, :id, :name, :include_blank => true %>
</p>
<p>
Price Range<br />
<%= f.text_field :minimum_price, :size => 7 %> -
<%= f.text_field :maximum_price, :size => 7 %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>
<% form_for @search do |f| %> <p> <%= f.label :keywords %><br /> <%= f.text_field :keywords %> </p> <p> <%= f.label :category_id %><br /> <%= f.collection_select :category_id, Category.all, :id, :name, :include_blank => true %> </p> <p> Price Range<br /> <%= f.text_field :minimum_price, :size => 7 %> - <%= f.text_field :maximum_price, :size => 7 %> </p> <p><%= f.submit "Submit" %></p> <% end %>
models/search.rb
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
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

