Question about finding with :include versus nested dynamic f


#1

I have a User model and a Status model. Each user is given a certain
status, either “Accepted”, “Rejected”, “OnHold”, “Declined”, etc. I
need to find all users with a status of “Accepted”, so I’m doing the
following:

in User.rb:

belongs_to :status

def accepted_users
status_id = Status.find_by_status_name(‘Accepted’).id
self. find_all_by_status_id(status_id)
end

I realize that I can also perform the above query by using something
like:

def accepted_users
User.find(:all, :include => ‘status’, :conditions =>
‘users.status_id = statuses.id and statuses.status_name = “Accepted”’)
end

but it seems to be much slower than the first version… I’m just
wondering if there’s anything really wrong with the first version (bad
form?), or if there might be a better way to do this… Any help is
appreciated, thanks,

Mike


#2

On 8-Jun-06, at 1:32 PM, Mike G. wrote:

status_id = Status.find_by_status_name(‘Accepted’).id

but it seems to be much slower than the first version… I’m just
wondering if there’s anything really wrong with the first version (bad
form?), or if there might be a better way to do this… Any help is
appreciated, thanks,

A couple of guesses why the second version might be appreciably
slower (there is no hard-and-fast rule here):

1 - the list of Users returned by your accepted_users() method is
rather large.

2 - you don’t have an index on users.status_id

In the case of ‘1’ you’re paying the price of the IO for a Status
record’s fields for each row returned when you :include => ‘status’.
By splitting the find into two steps you eliminate that IO (at the
expense of an extra query).

Item ‘2’ is made all the more problematic if item ‘1’ is true (no
index).

Regards,
Trevor

Trevor S.
http://somethinglearned.com