Asp Forum
Home
|
Login
|
Register
|
Search
Forums
>
comp.lang.ruby
Creating a search
Tom Ha
3/8/2008 10:40:00 AM
Hi there,
I just spent a night on the following "problem" and cant' figure it out
on my own:
I need to have a search function and thought I could do it like this:
- the search page has a form which takes the search criteria (people
only fill in the criteria they want to use for the search)
- upon submission of the form, the search criteria goes into
params[:search] (i.e. params[:search][:firstname],
params[:search][:lastname], params[:search][:gender], etc.)
- the controller takes the values from params[:search] and should
generate/write the appropriate "conditions" for the search statement
"User.find(:all, conditions => {...})"
- 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.
Question 1: Where is the mistake in my code? If I do it like below, I
get the error: "odd number list for Hash" (at line: see the comment in
the code). (Note: in this code I don't exclude the "empty" values.)
Question 2: How do I exclude key/value pairs with an "empty" value from
generating a "condition" (that would screw my search statement)?
The code until now looks like this:
def search
@searchresults = ''
if request.post?
@searchresults = User.find(:all, :conditions => {
# this should render like: 'firstname' =>
params[:search][:firstname],
# and no comma for the last: 'gender' =>
params[:search][:gender]
i=0 # <= I get the error for this line
params[:search].each do |key, value|
i+=1
if i < params[:search].length
puts "'"+key+"'"+" => params[:search][:"+key+"],"
else
puts "'"+key+"'"+" => params[:search][:"+key+"]"
end
end
})
end
end
I spent so many hours thinking about this that I would be really
thankful for a working solution!
Kind regards,
Tom
--
Posted via
http://www.ruby-...
.
2 Answers
Arlen Cuss
3/8/2008 12:14:00 PM
0
[Note: parts of this message were removed to make it a legal post.]
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/rubyon...
.
Secondly, we're still a nice bunch.
On Sat, Mar 8, 2008 at 9:39 PM, Tom Ha <tom999@gmx.net> 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
Tom Ha
3/8/2008 8:50:00 PM
0
Thanks a lot for your help, Arlen!
(Actually, the error "odd number list for Hash" still appears (for your
line of code) but I just learned some very useful things. I think the
problem is that I can't just write this code into the place where the
conditions should appear. I tried putting this new code into an
eval("...") statement, but it didn't change anything for the error.
Well, I'll follow your advice and ask the other group, then.)
> Instead, try something more functional:
> params[:search].reject {|key, val| val.nil?}.map {|k, v| "#{k.inspect} => #{v.inspect}"}.join(", ")
--
Posted via
http://www.ruby-...
.
Servizio di avviso nuovi messaggi
Ricevi direttamente nella tua mail i nuovi messaggi per
Creating a search
Inserendo la tua e-mail nella casella sotto, riceverai un avviso tramite posta elettronica ogni volta che il motore di ricerca troverà un nuovo messaggio per te
Il servizio è completamente GRATUITO!
x
Login to ForumsZone
Login with Google
Login with E-Mail & Password