Reputation: 13435
In my app, I have three models: Markets, Deals, and Users. Relationships are pretty straightforward:
class Market
has_many :users
has_many :deals
end
class User
belongs_to :market
end
class Deal
belongs_to :market
end
Now, in order to more easily query some of those relationships, the Market model has some methods attached to it:
class Market
def revenue_by_date(date)
deal = self.deals.find(:all, :select => 'id, purchased, price', :conditions => ["start_time =?", date])[0]
i = 0
if deal && deal.isMade?
i = deal.purchased * deal.price
end
return i
end
def users_for_market
return self.users.count
end
end
So, in my controller, I need to collect data pertaining to all of the markets together, and then I need to drill down in various places. So I have a query that looks like this:
markets = Market.find(:all, :order => :name, :include => [:users, :deals])
This runs the two include queries as expected, but later in my code where I do something like this:
markets.each do |m|
m.users_for_market
m.revenue_by_date(date_var)
end
it runs the individual queries in those model methods. I thought that the :include was supposed to supplant that?
What can I do to cut down on the number of queries I'm running?
Upvotes: 1
Views: 154
Reputation: 23317
:include is awesome, but if you call new database queries down the line, it won't stop you. You can reduce the DB hits though, by changing your Market methods:
class Market
def revenue_by_date(date)
deal = self.deals.select{|d| d.start_time == date}.first
i = 0
if deal && deal.isMade?
i = deal.purchased * deal.price
end
return i
end
def users_for_market
return self.users.size
end
end
Let's work backward - in users_for_market
, the count method does a db lookup, the size method just checks the array. In revenue_by_date
, I replaced your database query with a ruby select
method, which iterates over the items and only returns the ones where the select block equates to "true".
Rails won't stop you from making more database queries, but you can easily use ruby code to work with what you've already loaded. I hope this helps!
Upvotes: 1