From: Arlen Cuss Date: 2008-03-08T21:14:10+09:00 Subject: Re: Creating a search ------=_Part_40573_27341605.1204978458191 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi, Firstly, I'll make a note that this is the Ruby mailing list. You probably won't get many Rails-specific answers here, as we all-too-often are bombarded with requests for help with Rails specifics which most of us may prefer not to know. Here's their list address: http://groups.google.com/group/rubyonrails-talk. Secondly, we're still a nice bunch. On Sat, Mar 8, 2008 at 9:39 PM, Tom Ha wrote: > - But since submitting the search page/form with only *some* (not all) > fields filled in (or check boxes checked, or radio buttons clicked, > etc.) would generate some "empty" values in the key/value pairs in > "params[:search]", the generated search statement would be wrong because > for example a condition saying " 'gender' => nil/empty " could be added. > - So, only key/value pairs which have a value that's not empty should > generate the "condition" code. > @searchresults = User.find(:all, :conditions => { > i=0 # <= I get the error for this line Conditions is actually a Hash, or expecting a Hash, and indeed, this syntax is trying to construct a hash. Instead, it looks like you're writing a block instead - which can't work. Here's something to think about: >> {:a => nil, :b => 42}.reject {|k,v| v.nil?} => {:b=>42} >> Hash#reject takes a block, returning a new hash, excluding the values for which the block returned true. (i.e. true, since we say yes to `rejecting') It looks like you tried to embed a function/set of methods into the hash above (:conditions => {stmt; stmt;...}), but we can't do that. Instead, try something more functional: params[:search].reject {|key, val| val.nil?}.map {|k, v| "#{key.inspect} => #{value.inspect}"}.join(", ") This does pretty much everything you try to do here with the loop, and it's a bit more concise. Here's how to read it: params[:search].reject {|key, val| val.nil?} This returns a new hash without any key/val-pair where the value is `nil'. Replace `val.nil?' with your own condition that returns `true' when you don't that value. .map {|k, v| "#{key.inspect} => #{value.inspect}"} This goes through each key/val-pair in the hash, and returns an array. Here's an example of the output: >> {:a => nil, :b => 42}.map {|k,v| "#{k.inspect} => #{v.inspect}"} => [":b => 42", ":a => nil"] >> .join(", ") This does what your loop was trying to do, though slightly more concisely. Array#join takes one argument and uses that as the `separator', stringing the elements together with that between. >> [":b => 42", ":a => nil"].join ", " => ":b => 42, :a => nil" >> Hope this helps. Arlen ------=_Part_40573_27341605.1204978458191--