views:

41

answers:

2

Hi everybody! (Hi Dr. Nick!)

I'm trying to tighten things up for our app admin, and in a few places we have some pretty skeezy code.

For example, we have Markets, which contain Deals. In several places, we do something like this:

@markets = Market.find(:all, :select => ['name, id'])
@deals = Deal.find(:all, :select => ['subject, discount_price, start_time, end_time'], :conditions => ['start_time >= ? AND end_time <= ?', date1 date2])

Then in the corresponding view, we do something like this:

@markets.each do |m|
  =m.name
end

@deals.sort!{ |a,b| a.market.name <=> b.market.name }
@deals.each do |d|
  =d.subject
  =d.market.name
end

This runs a stupid amount of queries: one to get the market names and ids, then another to get all the deal info, and then for each deal (of which there are thousands), we run yet another query to retrieve the market name, which we already have!

Tell me there is a way to get everything I need with just one query, since it's all related anyway, or at least to clean this up so it's not such a nightmare.

Thanks

A: 

If you use :include => :market when searching the deals you won't run a query to retrieve the market name for each deal. It'll be eager loaded.

@deals = Deal.find(:all, :include => :market)

Hope it helps.

j.
I had thought of that, but then I'm still needing something for the @markets.each do { |m| = m.name } block
Kevin Whitaker
The way I told you, you'll solve your problem with 3 queries. I can't think any other way to do this using less queries. If you change your view to one loop only, you can reduce to 2 queries.
j.
A: 

You can write like this way ..

@deals_with_market_name = Deal.find(:all, :include => :market, 
:select => ['subject, discount_price, start_time, end_time,market.name as market_name'], 
:conditions => ['start_time >= ? AND end_time <= ?', date1 date2], 
:order => "market.name")

And in view ...

@deals.each do |a|
  =a.subject
  =a.market_name
end

Try it...

krunal shah