Tuesday, March 1, 2011

How can I use the Rails "find" method to perform an AND or an OR query?

Let's assume I have a model called "product." Let's assume that product has three fields. These fields are 'name' (type string), 'cost' (type integer), and 'is_visible' (type bool).

1) How can I do a search query using the Rails "find" method (if there is another method, that's fine) so that I can search for all products with a cost greater than 100 AND is_visible is true?

2) What if we wanted to change this to search to where name != '' OR cost == 0?

This isn't a problem to do an SQL, but I would like to think that Rails has a way to do AND/OR queries to the database without using SQL.

Thanks!

From stackoverflow
  • You would need to use the conditions option on the find method. The conditions option can be either a Hash, Array, or String. There are lots of options for conditions, so I recommend reading the API help for it. For example if you want to (1):

    Product.find(:all, :conditions => ['cost > ? and is_visible is true', 100])
    

    Or (2)

    Product.find(:all, :conditions => ["name != '' or cost =0])
    
    Adam Byrtek : I don't think "is true" is a correct SQL92 syntax...
    allesklar : According to rails api doc it should 'be = true' but Adam you seem to have missed the point in your answers and here that it's a Rails question no a SQL question. For many of us the Rails way is just easier and better.
    Adam Byrtek : Actually everything you include in :conditions will be embedded directly into the SELECT statement generated by ActiveRecord - so this definitely has something to do with SQL.
  • This is exactly the problem SQL was designed to solve, so why not to use it? Just add an appropriate :condition and your problem is solved.

    JP : Because I have been spoiled by LINQ.
    Adam Byrtek : I see, so I elaborated on this in my second answer - hope that helps.
    Adam Byrtek : The fact this was downvoted only convinces me to the surprising fact that most Rails developers are afraid of SQL. This is interesting, as SQL is a great example of an external DSL, and Rails folks generally like DSLs.
  • If you want something like LINQ you can check alternative Ruby ORMs like DataMapper or Sequel that provide more complex filtering capabilities.

    For example in Sequel 2 you can write:

    items.filter((:cost > 100) & (:is_visible = 1))
    

    You can also use the bitwise "|" operator to get OR condition.

    In DataMapper this will look like:

    Model.all(:cost.gt => 100, :is_visible.eq => 1)
    

    However some people don't like the fact that those features are implemented by overloading the standard Symbol class.

0 comments:

Post a Comment