Habit
Habit

Reputation: 845

What does .find(:all ) with specific conditions return in Ruby on Rails?

I'm not sure if I worded the question correctly, but I'm trying to figure out what this line of code actually does:

@orderdata = Order.find(:all, :conditions => ["customer_ID = ?",@data])

Here's what Orders table contains in my SQL database:

Orders

+-------+------------+-------------+
| id    | order_date | customer_ID |
+-------+------------+-------------+
| 12475 | 2008-09-01 | 522         |
| 12476 | 2008-09-01 | 311         |
| 12477 | 2008-09-01 | 567         |
| 12478 | 2008-09-01 | 587         |
| 12482 | 2008-09-01 | 124         |
| 12483 | 2008-09-01 | 315         |
| 12484 | 2008-09-02 | 256         |
| 12489 | 2008-09-02 | 311         |
| 12494 | 2008-09-04 | 315         |
| 12495 | 2008-09-04 | 256         |
| 12498 | 2008-09-05 | 522         |
| 12504 | 2008-09-06 | 522         |
+-------+------------+-------------+

So once again, I'll add the line of code so you don't have to scroll back up:

@orderdata = Order.find(:all, :conditions => ["customer_ID = ?",@data])

I read a few things about what Ruby on Rails does with this .find() function and I've come to believe that it returns an array of some sort, but not sure exactly of what.

@data is user input in a text field HTML form, which should be a customer number. So I believe this line of code is creating an array called @orderdata, and filling it. It is looking in the Orders table to find all occurrences of key customer_ID where it is equal to @data (the user entered customer number/id).

I guess my question is essentially: what will be in @orderdata? And how do I access the values in it?

Thanks!

Upvotes: 2

Views: 934

Answers (2)

MrYoshiji
MrYoshiji

Reputation: 54882

This code:

@data = 12 # for the example
@orderdata = Order.find(:all, :conditions => ["customer_ID = ?", @data])

Will build an array of Order objects responding to the following SQL:

SELECT * FROM orders WHERE orders.customer_ID = 12;

To access the values of this array, you can either loop on it, or just select the first/last:

@orderdata.first # returns the first Order object of the array ; nil if list is empty
@orderdata.last # returns the last Order object of the array ; nil if empty

# loop through each element of the array and display it's attribute "customer_ID" (Rails Console style):
@orderdata.each do |order|
  puts order.customer_ID
end

I recommend you to use the .where() method instead of the find:

c_id = 12
Order.where(customer_id: c_id) # returns a list of Order having 12 as customer_id

Fun thing with the .where() method, you can chain-scope your queries:

orders = Order.where(paid: false)
orders = orders.where(customer_id: c_id) if c_id.present? # add the conditions if c_id is defined
orders = orders.where(order_date: (Date.today-1.day..Date.today)) # returns all the orders where their order_date is between yesterday & today

Same way as a regular array, to access first & last element of the array:

orders = Order.where(paid: false)
orders.first # returns the first of the list
orders.last  # returns the last

Upvotes: 1

Nobita
Nobita

Reputation: 23713

First of all, using Model.find(:all, :conditions => ...) is deprecated. Instead you should be using Model.all(:conditions =>...)

And, answering your question. In @orderdata it will be an Array containing all of the objects that matches the given conditions (in your case an Array of Order objects which match customer_ID = 'some_id' )

You could have actually answered the question yourself by opening the Rails console and do:

Order.find(:all, :conditions => ["customer_ID = ?",@data]).class

Then, how could you access these results? Well, as you would access any Ruby array. If you want to loop through all the results, you could do:

@orderdata.each do |order|
 # Do whatever you want with a particular order.
end

Upvotes: 2

Related Questions