Dave
Dave

Reputation: 1175

How can I have multiple searches?

I have a venues model where each venue belongs to an area and a type. I have 2 forms consisting of checkboxes on the index page allowing me to filter venue records shown by either which type or area they belong to. However only the last line in the def index is being used, how can I combine them so that both forms are active?

Controller:

class VenuesController < ApplicationController

  def index
    @venues = Venue.all(:conditions => {:area_id => params[:areas]})
    @venues = Venue.all(:conditions => {:venuetype_id => params[:venuetypes]})
  end
end

View:

<div class="filter_options_container">

  <form class="filter_by_area_form", method="get">
    <% Area.all.each do |a| %>
      <%= check_box_tag("areas[]", a.id) %>
      <%= a.name %>
    <% end %>
    <input type="submit" value="Filter" />
  </form>

  <br><br>

  <form class="filter_by_venuetype_form", method="get">
    <% Venuetype.all.each do |v| %>
      <%= check_box_tag("venuetypes[]", v.id) %>
      <%= v.name %>
    <% end %>
    <input type="submit" value="Filter" />
  </form>
</div>

<div class="venue_partials_container">
  <%= render :partial => 'venue', :collection => @venues %>
  <div class="clearall"></div>
  <%= link_to 'add a new venue', new_venue_path, :class => "add_new_venue_button" %>
</div>

So only the venuetype form works, or if I change the def index to read:

  def index
    @venues = Venue.all(:conditions => {:venuetype_id => params[:venuetypes]})
    @venues = Venue.all(:conditions => {:area_id => params[:areas]})
  end

Then only the areas form works.

EDIT

Ive changed the controller to read:

  def index
    @venues = Venue.all(:conditions => {:venuetype_id => params[:venuetypes]}&&{:area_id => params[:areas]})
  end

and the view to:

<div class="filter_options_container">
  <form class="filter_form", method="get">
    <fieldset class="filter_form_fieldset">
      <% Area.all.each do |a| %>
        <%= check_box_tag("areas[]", a.id) %>
        <%= a.name %>
      <% end %>
    </fieldset><br>

    <fieldset class="filter_form_fieldset">
      <% Venuetype.all.each do |v| %>
        <%= check_box_tag("venuetypes[]", v.id) %>
        <%= v.name %>
      <% end %>
      <input type="submit" value="Filter" />
    </fieldset>
  </form>
</div>

After selecting an area and a type from the form and clicking the submit button the URL displays "/venues?areas[]=2&venuetypes[]=13" but is still only filtering the results by area and not type.

Thanks for any help.

Upvotes: 0

Views: 135

Answers (1)

wuputah
wuputah

Reputation: 11395

For building search queries up, you might use scoped:

Rails 2

@venues = Venue.scoped
@venues = @venues.scoped(:conditions => { :venuetype_id => params[:venuetypes] }) if params[:venuetypes].present?
@venues = @venues.scoped(:conditions => { :area_id => params[:areas] }) if params[:areas].present?

If you create named scopes like @Steve Smith suggested:

class Venue < ActiveRecord::Base
  named_scope :with_type, lambda { |types|
    types.present? ? { :conditions => { :venuetype_id => types } } : {} }
  named_scope :with_area, lambda { |areas|
    areas.present? ? { :conditions => { :area_id => areas } } : {} }
end

Then you can simply do:

@venues = Venue.with_type(params[:venuetypes]).with_area(params[:areas])

Rails 3

@venues = Venue.scoped
@venues = @venues.where(:venuetype_id => params[:venuetypes]) if params[:venuetypes].present?
@venues = @venues.where(:area_id => params[:areas]) if params[:areas].present?

Or:

class Venue < ActiveRecord::Base
  scope :with_type, lambda { |types|
    types.present? ? where(:venuetype_id => types) : scoped }
  scope :with_area, lambda { |areas|
    areas.present? ? where(:area_id => areas) : scoped }
end

Then you can simply do:

@venues = Venue.with_type(params[:venuetypes]).with_area(params[:areas])

Upvotes: 2

Related Questions