Mike Garey
2006-Jun-08 20:32 UTC
[Rails] question about finding with :include versus nested dynamic finder (bad form? efficiency?)
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
Trevor Squires
2006-Jun-08 20:59 UTC
[Rails] question about finding with :include versus nested dynamic finder (bad form? efficiency?)
On 8-Jun-06, at 1:32 PM, Mike Garey wrote:> 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, >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 Squires http://somethinglearned.com> Mike > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails