11

This might be more of a Ruby syntax thing than anything else. I'm having difficulty getting two limiting conditions on a SomeObject.find going.

Separated, the conditions seem to work:

if search != ''
  find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
else
  find(:all, :conditions => ['active', 1]).shuffle
end

What I'm going for for the first case is this:

find(:all, :conditions => ['name LIKE ?', "%#{search}%"], ['active', 1])

But the line throws syntax error, unexpected ')', expecting tASSOC.

Will Matheson
  • 338
  • 1
  • 4
  • 19

4 Answers4

17

Rails 2

find(:all, :conditions => ['name LIKE ?', "%#{search}%"], ['active', 1]) isn't the proper syntax for passing hashes to a method. You can leave the curly braces off of a hash if it is the last argument to a method, but in this case you are passing an array as the last argument.

Use the following instead:

find(:all, :conditions => ["name LIKE ? AND active = ?", "%#{search}%", 1])

or

params = {:search => "%#{search}%", :active => 1}
find(:all, :conditions => ["name LIKE :search AND active = :active", params])

Rails 3 and 4

You would probably want to do something more like the following for recent Rails versions:

 scope :active, -> { where(active: true) }
 scope :name_like, ->(search) { where("name LIKE ?", "%#{search}%") }

And then you'd call it like this:

YourModel.active.name_like("Bunnies")

That allows you to reuse those specific queries in different combinations throughout the application. It also makes the code retrieving the data super easy to read.

If you don't like the scope syntax, you can also define these as class methods:

def self.active
  where(active: true)
end

def self.name_like(search)
  where("name LIKE ?", "%#{search}%")
end

You can also chain scopes on the fly. That will allow you to start building a chain of relation objects and then choose to include others based on conditions. Here's what it could look like when applied to the original question to achieve the same results:

results = active
results = results.name_like(search) if search.present?
  • Thanks very much! Your second example worked for me (didn't try the first - the second looks like a nice way to go to add any number of conditions so I don't have to worry about the order of them quite so much). – Will Matheson May 23 '13 at 15:13
2

Instead of using if-else which would involve a redundancy for checking on active = 1, a simpler syntax would be something like this:

result = where(:active => 1)
result = result.where('name like ?', "%#{search}%") unless search.blank?

As far as the error your seeing, it wouldn't appear to be caused by the code that you are posting. A stack trace may help narrow it down further...

PinnyM
  • 35,165
  • 3
  • 73
  • 81
  • Yeah, if I were stopping here, it would be sort of redundant, but I want to do things like only shuffle the results if no search string was entered and I want to add additional conditions / statements on top of this foundation. Thanks for your answer! – Will Matheson May 23 '13 at 15:18
2

i think you are using rails 2

try this.

find(:all, :conditions => ['name LIKE ? and active = 1', "%#{search}%"])

rails 3 syntax

where('name LIKE ? and active = 1', "%#{search}%")
Sachin Singh
  • 7,107
  • 6
  • 40
  • 80
  • I'm using Rails 3, but I got the original search snippet from a 2007 tutorial: http://railscasts.com/episodes/37-simple-search-form – Will Matheson May 23 '13 at 15:06
0

For Rails 4, In rails new find_by and find_by! methods are introduced

Read answer

Community
  • 1
  • 1
Deepak Kabbur
  • 774
  • 14
  • 25