# Syntax Help

**URL:** <https://www.ruby-forum.com/t/syntax-help/179785>\
**Category:** Rails\
**Created:** [December 3, 2009, 7:27pm UTC](https://www.ruby-forum.com/t/syntax-help/179785 "2009-12-03T19:27:33Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![scrozier](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/48db29/32.png) [@scrozier](https://www.ruby-forum.com/u/scrozier)\
**Post date:** [December 3, 2009, 7:27pm UTC](https://www.ruby-forum.com/t/syntax-help/179785/1 "2009-12-03T19:27:33Z")

</div>

Can someone please help me with the following syntax? I’m passing two  
arguments to a definition in my model (passing some session info to the  
model), and I can’t seem to get the multiple conditions down right.

def self.search(search, user\_id)  
if search  
find(:all, :conditions =\> [‘firstname LIKE ?’, “#{search}”, ’ AND  
user\_id == ?’, “#{user\_id}”])  
else  
find(:all, :conditions =\> [‘user\_id == ?’, “#{user\_id}”])  
end  
end

I probably have a comma in there, but is something like this possible?  
Two arguments sent to the definition in my model, and using both those  
arguments to filter out the records that I find?

---

<div class="post-metadata">

**Author:** ![scrozier](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/48db29/32.png) [@scrozier](https://www.ruby-forum.com/u/scrozier)\
**Post date:** [December 3, 2009, 7:41pm UTC](https://www.ruby-forum.com/t/syntax-help/179785/2 "2009-12-03T19:41:27Z")

</div>

Steve C. wrote:

> Can someone please help me with the following syntax? I’m passing two  
> arguments to a definition in my model (passing some session info to the  
> model), and I can’t seem to get the multiple conditions down right.
> 
> def self.search(search, user\_id)  
> if search  
> find(:all, :conditions =\> [‘firstname LIKE ?’, “#{search}”, ’ AND  
> user\_id == ?', “#{user\_id}”])

Note that “#{var}” is always bad syntax. var.to\_s or simply var will  
work just as well.

But anyway, your problem is simple. In the array syntax of :conditions,  
the strings aren’t paired – rather, the first string is the _entire_  
SQL fragment, and _then_ come all the parameters.

> ```
> else
> find(:all, :conditions => ['user_id == ?', "#{user_id}"])
> 
> ```

Here, you don’t want the array syntax of :conditions. Use the hash  
syntax, or find\_all\_by\_user\_id.

> ```
> end
> 
> ```
> 
> end
> 
> I probably have a comma in there, but is something like this possible?  
> Two arguments sent to the definition in my model, and using both those  
> arguments to filter out the records that I find?

Yes.

Best,  
–Â  
MarnenÂ Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![scrozier](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/48db29/32.png) [@scrozier](https://www.ruby-forum.com/u/scrozier)\
**Post date:** [December 3, 2009, 8:40pm UTC](https://www.ruby-forum.com/t/syntax-help/179785/3 "2009-12-03T20:40:54Z")

</div>

Marnen Laibow-Koser wrote:

> Note that “#{var}” is always bad syntax. var.to\_s or simply var will  
> work just as well.
> 
> But anyway, your problem is simple. In the array syntax of :conditions,  
> the strings aren’t paired – rather, the first string is the _entire_  
> SQL fragment, and _then_ come all the parameters.

Gotcha - thanks for the tip. I stripped out the #{var}, and simply used  
var and it worked just as well. I got that syntax from Ryan B. over  
at Railscasts, but I was watching a pretty old episode so I’m sure  
things had changed since then.

> Here, you don’t want the array syntax of :conditions. Use the hash  
> syntax, or find\_all\_by\_user\_id.

I had a little trouble initially figuring that one out, but I’m sure I  
got it working now. I guess for a beginner syntax of simple things like  
arrays and hashes are one of the biggest hurdles to overcome. At least  
that’s how it is in my case.

It’s all a learning process though!

Here’s the result; look pretty good?

def self.search(search, user\_id)  
if search  
find(:all, :conditions =\> [’(firstname LIKE ? OR lastname LIKE ?)  
AND user\_id == ?’,  
search,  
search,  
user\_id  
])  
else  
find(:all, :conditions =\> { :user\_id =\> user\_id })  
end  
end

---

<div class="post-metadata">

**Author:** ![scrozier](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/48db29/32.png) [@scrozier](https://www.ruby-forum.com/u/scrozier)\
**Post date:** [December 3, 2009, 9:28pm UTC](https://www.ruby-forum.com/t/syntax-help/179785/4 "2009-12-03T21:28:07Z")

</div>

Steve C. wrote:  
[…]

> I stripped out the #{var}, and simply used  
> var and it worked just as well. I got that syntax from Ryan B. over  
> at Railscasts, but I was watching a pretty old episode so I’m sure  
> things had changed since then.

It was never a good syntax, and I’m not sure why Ryan would be using it.  
Now, it’s great if you’re doing “#{var} with other stuff”, but it’s  
silly if there’s no other stuff.

[…]

> Here’s the result; look pretty good?

Mostly.

> def self.search(search, user\_id)  
> if search  
> find(:all, :conditions =\> [‘(firstname LIKE ? OR lastname LIKE ?)  
> AND user\_id == ?’,  
> search,  
> search,  
> user\_id

Why not use named placeholders? That way you don’t have to supply the  
same variable twice.

> ```
> ])
> else
> find(:all, :conditions => { :user_id => user_id })
> 
> ```

Again, I’d recommend find\_all\_by\_user\_id for something this  
straightforward.

> ```
> end
> 
> ```
> 
> end

Best,  
–Â  
MarnenÂ Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![scrozier](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/48db29/32.png) [@scrozier](https://www.ruby-forum.com/u/scrozier)\
**Post date:** [December 3, 2009, 9:59pm UTC](https://www.ruby-forum.com/t/syntax-help/179785/5 "2009-12-03T21:59:22Z")

</div>

Marnen Laibow-Koser wrote:

> Why not use named placeholders? That way you don’t have to supply the  
> same variable twice.

> Again, I’d recommend find\_all\_by\_user\_id for something this  
> straightforward.

Thanks a bunch! You’ve motivated me to learn more about named  
placeholders, and after doing some research  
([http://www.robbyonrails.com/articles/2005/10/21/using-named-placeholders-in-ruby](http://www.robbyonrails.com/articles/2005/10/21/using-named-placeholders-in-ruby))  
this page helped me understand how to use them in my particular example.

Now then - how does this look? Maybe it’s because I’m new, but I find  
refactoring pretty neat. It’s fun to have code that works, be  
simplified into even easier to understand and manage code.

I need to get out of the habit of leaving a problem just because it’s  
fixed. Nine times out of ten it could be refactored into better code,  
which surely helps me in the long run.

The code:

def self.search(search, user\_id)  
if search  
values = { :search =\> search, :user\_id =\> user\_id }  
conditions = “user\_id = :user\_id AND (firstname LIKE :search OR  
lastname LIKE :search)”  
find(:all, :conditions =\> [conditions, values])  
else  
find\_all\_by\_user\_id(user\_id)  
end  
end
