Reputation: 1175
I'm super new to programming and am stuck... again,
I'm using rails 3 and currently have a venue model where each venue belongs to an area and a type (which are each thier own models) all of the venues in the database are displayed at the index page in partitions displaying the venue name, and its area and type.
How can I go about having a form with 2 dropdowns (areas and types) on the index page which filter the venue records shown depending on what is selected in the dropdowns. e.g. select pubs as type and Manchester as area and only the pubs in Manchester are shown or select pubs as type and all as area and all the pubs from all areas are shown.
I have tried installing sphinx and thinking_sphinx but can't seem to get them working on my windows 7. I got as far as a 1067 error on service startup and a "Failed to start searchd daemon." from thinking_sphinx on rake ts:start, which im presuming is from the sevice not running, so I'm hoping the answer to this won't involve sphinx.
I've had a look at scopes and am thinking this could possibly be the way to go? Although I haven't got the first idea as to how to include a dropdown to select the scope needed or indeed how to write a scope which will satisfy the kind of filter I want.
Thanks very much for any help, its much appreciated!
Upvotes: 1
Views: 4387
Reputation: 24515
You can do this in several ways, depending on how exactly you want to filter. The best is to build the filter into a .find(:conditions => ...)
call and let the database do the hard work. If you don't know beforehand on what parameters you are going to filter, it's easier but less efficient to do it in code. Assuming you have search parameters venue_area
and venue_type
, you could do something like this in the controller:
def index
@venues = Venue.all # Or whatever criteria you might have here
@venues = @venues.select { |v| v.area_id == params[:venue_area] } if !params[:venue_area].blank?
@venues = @venues.select { |v| v.type_id == params[:venue_type] } if !params[:venue_type].blank?
...
end
You then create dropdowns containing all type and area ID:s in your search form. There are several helpers you can use for this, such as select_tag
. The @options
would be better populated in the controller, of course, but this shows the relationship clearer:
<form method="get">
<% @options = Area.all.map { |a| [ a.name, a.id ] } %>
<%= select_tag("venue_area", options_for_select(@options)) %>
<input type="submit" value="Filter" />
</form>
Upvotes: 0
Reputation: 4275
In your controller you should be able to do something as simple as:
@filtered_venues = Venue.where(:area => params[:venue][:area], :type => params[:venue][:type]).all
That should give you the filtered results that you want.
And then in your view you should be able to use form helpers to create the select elements:
select("venue", "area", ['New York', 'London', 'Amsterdam'], {}, { :prompt => 'Select Area' })
select("venue", "type", ['Pub', 'Outdoor', 'Hall'], {}, { :prompt => 'Select Type' })
Should output something like:
<select name="venue[area]">
<option value="">Select Area</option>
<option value="New York">New York</option>
<option value="London">London</option>
<option value="Amsterdam">Amsterdam</option>
</select>
<select name="venue[:type]">
<option value="">Select Type</option>
<option value="Pub">Pub</option>
<option value="Outdoor">Outdoor</option>
<option value="Hall">Hall</option>
</select>
There are a lot of other ways to get the options in there dynamically if you have collections ready for area or type. Check out the following for more information: http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html
Upvotes: 1
Reputation: 37141
This type of filtering could be done in either JavaScript, Ruby, or both.
If the HTML itself contains all the metadata you need to determine which items match which filters, then it could be done entirely in JavaScript by hiding and showing elements in response to a change in the form.
If the user is required to click a submit button for their chosen filters to take effect, then the form could simply submit and you could repopulate the form on the back end with Rails.
If the HTML doesn't have all the metadata and you don't want them to have to submit a form, you can use AJAX to send the chosen filters to the back end, have Rails construct the new form and send it back to the client, and then use JavaScript to update the front end.
You may get a few ideas from the Railscasts episode Search, Sort, Paginate with AJAX. It's not exactly your situation, but it might point you in the right direction for how these types of operations work in general.
Upvotes: 0