[newb] Find vs Find :all question

I’m playing out with writing an online store.

So far it has accounts, addressbooks, and orders, and those 3 are tied
together with an customer ID. I also have orderDetails, which are
associated to the order via an order number. See models below…

When I do the following I can access the orderDetails information just
fine:

@order = Order.find(params[:id]) # i pass it a customer id

and i could access the orderDetails by doing this:

<%for detail in @order.orderDetails %>
	item #: <%=detail.itemId%><br>etc etc
<%end%>

However, not all customers have orders, so it sometimes would return
RecordNotFound error.

So, i changed it to:

@order = Order.find(:all, :conditions => ["customerId = ?", 

params[‘customerId’]])

which still works. But, now i cannot access the orderDetails the same
way, it says:
undefined method `orderDetails’ for []:Array

Have no clue what I’m doing wrong.

Does just plain old find return something different than find :all?

Here are my models:


class Account < ActiveRecord::Base
set_primary_key ‘customerId’
has_many :addressbooks, :foreign_key => ‘customerId’
has_many :orders, :foreign_key => ‘customerId’
end

class Addressbook < ActiveRecord::Base
belongs_to :account
end

class Order < ActiveRecord::Base
set_primary_key “customerId”
belongs_to :account
has_many :orderDetails, :foreign_key => ‘orderNumber’, :finder_sql =>
'SELECT * ’ +
'FROM orderDetails od ’ +
‘WHERE od.orderNumber = #{orderNumber}’
end

class OrderDetail < ActiveRecord::Base
set_table_name “orderDetails”
belongs_to :order
end


Thanks!

Find(:all) returns an array of multiple records. Try using find
(:first) instead, which will return the first record it comes across
matching your criteria.

David C. wrote:

I’m playing out with writing an online store.

So far it has accounts, addressbooks, and orders, and those 3 are tied
together with an customer ID. I also have orderDetails, which are
associated to the order via an order number. See models below…

When I do the following I can access the orderDetails information just
fine:

@order = Order.find(params[:id]) # i pass it a customer id

and i could access the orderDetails by doing this:

<%for detail in @order.orderDetails %>
item #: <%=detail.itemId%>
etc etc
<%end%>

However, not all customers have orders, so it sometimes would return
RecordNotFound error.

So, i changed it to:

@order = Order.find(:all, :conditions => ["customerId = ?", 

params[‘customerId’]])

which still works. But, now i cannot access the orderDetails the same
way, it says:
undefined method `orderDetails’ for []:Array

Have no clue what I’m doing wrong.

Does just plain old find return something different than find :all?

When you do Order.find(:all, …) you will get an array of ActiveRecord
objects, which is why you are getting an undefined method error.

If you only want to find one record, but pass it conditions, use this:

@order = Order.find(:first, …)

Also, your find condition may have a problem in that customerId would be
an integer, but using the ‘customerId = ?’ style will (I believe) quote
the argument, thus giving a WHERE customerId = ‘5’ for example.

@order = Order.find(params[:id]) is the same idea as Order.find
(:first, :conditions => “id = #{params[:id]}”). When you’re searching
by ID, you’re searching for a unique record, which will return the
actual record instead of an array of records.

Dylan M. wrote:

@order = Order.find(params[:id]) is the same idea as Order.find
(:first, :conditions => “id = #{params[:id]}”). When you’re searching
by ID, you’re searching for a unique record, which will return the
actual record instead of an array of records.

So how do I access the records in the array? Having trouble finding the
syntax for that.

Thanks!

The same way you were trying to iterate through your orderDetails.

<% @orders = Order.find(:all, :conditions…) %>
<% for order in @orders %>
<% for detail in order.orderDetails %>
item #: <%=detail.itemId%>
etc etc
<% end %>
<% end %>

When you do Order.find(:all, …) you will get an array of ActiveRecord
objects, which is why you are getting an undefined method error.

This returns multiple orders and still works
@order = Order.find(params[:id])
is this not an array but something different?

If you only want to find one record, but pass it conditions, use this:

@order = Order.find(:first, …)

I don’t necessarily need to pass it a specific condition, just don’t
want RecordNotFound errors or have to catch that with a rescue
statement.

There could be more than 1 order, so :first won’t work in this case. I
have the models for order and orderDetails as:

class Order < ActiveRecord::Base
set_primary_key “customerId”
belongs_to :account
has_many :orderDetails, :foreign_key => ‘orderNumber’, :finder_sql =>
'SELECT * ’ +
'FROM orderDetails od ’ +
‘WHERE od.orderNumber = #{orderNumber}’
end

class OrderDetail < ActiveRecord::Base
set_table_name “orderDetails”
belongs_to :order
end

so I just need to be able to access the orderDetails part of the order
object. Guess I just don’t know how to access it.

Thanks for the help!