Forum: Ruby on Rails filtering "tags" via checkboxes - HABTM

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
73680da1994fb3341d4f51632f82848a?d=identicon&s=25 Don Cento (Guest)
on 2006-02-22 21:28
(Received via mailing list)
First post/newbie post... bear with me.

What I'm trying to achive (music site):
A system containing tracks and moods with a HABTM relationship. I've
got all that set up and functioning in the admin environment - i.e.
admins can apply a variety of moods to a particular track via a
series of checkboxes. Join table works just fine.

I'm currently stuck on allowing site users to filter a list of moods
via checkboxes to see only those tracks that are "tagged" with the
selected mood or moods. In my hacking I've got it working for a
single mood, but multiple moods.... nada.

My def results needs some help. I'm lost in the woods. Any insight
would be very appreciated. Code below:

Don

Here's an excerpt of the error that might helpful.

Parameters: {"commit"=>"Show Tracks", "moods"=>["1", "2"]}

MOODS_CONTROLLER.RB
   def results
     params[:moods].each do
       #@my_id=mood
     end
     mood = Mood.find(4) # hard coded for a single query.
     @tracks_by_mood = mood.tracks
   end

LIST.RHTML
<h1>Moods</h1>
<p>Select a mood or moods below to see a list of track with those
moods</p>
<ul>
<%= start_form_tag :action => 'results', :id => @mood %>
	<% Mood.find(:all).each do |mood| %>
		<li><%= check_box_tag("moods[]",mood.id) %><b><%= mood.name %> - </
b><%= mood.description%></li>
	<% end %>
	<%= submit_tag 'Show Tracks' %>
<%= end_form_tag %>
</ul>

RESULTS.RHTML
<h1>Results</h1>
<table>
<% for track_by_mood in @tracks_by_mood %>
	<tr>
		<td><b><%= track_by_mood.title %></b></td>
		<td>
			<% for mood in track_by_mood.moods %>
				<%= mood.name %>,
			<%end%>
		</td>
	</tr>
<%end%>
</table>
0df56f2edb0d80e81c5c0ef1ca91690e?d=identicon&s=25 Joel Oliveira (Guest)
on 2006-02-22 23:08
(Received via mailing list)
This is a great question.  I'm trying to do something similar in a
demo application I'm putting together that searches through apartment
listings.  I'm trying to accomplish the same as Don but in my case I'm
looking to filter searches with multiple bedroom sizes ... IE:  search
for apartments that are studios, 1br, or 2br ...

for the life of me I can't figure out how to create the call to
find_all with all of the selected checkboxes though.

- J
0df56f2edb0d80e81c5c0ef1ca91690e?d=identicon&s=25 Joel Oliveira (Guest)
on 2006-02-22 23:44
(Received via mailing list)
I guess it's a good thing that this always happens, but, of course as
soon as I sent this email I had a "lightbulb" moment and figured it
out.

Don - This might work, try this:

def results
  moodsearch = ""
  params[:moods].each { |eachmood| moodsearch=moodsearch+" OR
mood='"+eachmood+"'"}
  moodsearch = moodsearch.slice!(3, moodsearch.length)
  mood = Mood.find(:all, :conditions => moodsearch)
  @tracks_by_mood = mood.tracks
end

basically I figured we should build the search condition dynamically
by looping through the checked values in the moods array.  throw the
string that's built in there as the conditions, and search away.  (The
slice method is just there to get rid of the head "OR ".)

I tried this in my own applicaction and it worked out perfectly.

- Joel
42172acdf3c6046f84d644cb0b94642c?d=identicon&s=25 Pat Maddox (pergesu)
on 2006-02-22 23:53
(Received via mailing list)
How about:

moods = params[:moods].join(", ")
Mood.find(:all, :conditions => "mood in (#{mood})")

Totally untested, but I think it'll work, and you should be able to
adapt it. WAY prettier than looping/slicing  :)

Pat
0df56f2edb0d80e81c5c0ef1ca91690e?d=identicon&s=25 Joel Oliveira (Guest)
on 2006-02-23 00:06
(Received via mailing list)
Yup - that works just as well and looks much more elegant than my
solution.  Thank you Pat!

- Joel
8e44c65ac5b896da534ef2440121c953?d=identicon&s=25 Ezra Zygmuntowicz (Guest)
on 2006-02-23 18:55
(Received via mailing list)
Guys-

	Be careful with this. As it stands you are not escaping the params
you are putting in the :conditions search. So you are leaving
yourself open to sql injection attacks.

	If you use my ez_where plugin you can do this same search like this:

@moods = Mood.ez_find(:all) { mood === params[:moods] }

	The === operator and this ez_find method will create this where clause:

   :conditions => ["mood IN (?)", params[:moods] ]

where params[:moods] is an array of the check boxes.

	You can read more and get the download link to this plugin here:

http://brainspl.at/articles/2006/01/30/i-have-been-busy

	There is a ton of other cool features that make multi param searches
a lot cleaner in the plugin


Cheers-
-Ezra
This topic is locked and can not be replied to.