views:

276

answers:

2

I'm using named scopes to process some filtering actions, and the log is showing that everything is working perfectly, except that after the app goes and finds the correct data, it then ignores what it found and just lists a find.all instead of the filtered result. Here's the details.

I have 3 models: Users, Markets and Schedules.

User has_many :schedules
User has_many :markets, :through => :schedules

Market has_many :schedules
Market has_many :users, :through => :schedules

Schedule belongs_to :user Schedule belongs_to :market

On the "show" page for each market, I display the users who sell things at that market. I also display the days of the week that such users are at the market. This data is contained in the join model (i.e. schedules).

On the market page, I need to support filtering the users by day of the week that the user is at the market.

In my Market controller, I have this:

    def show
      @market = Market.find(params[:id])
      @users = @market.users.filter_marketdate(params[:filter])
    end

In my Market model, I have this:

def self.filter_marketdate(filter)
 case filter
  when 'monday' then monday.all
   else find(:all)
 end
end

In my User model, I have this:

named_scope :monday, :include => :schedules, :conditions => {'schedules.monday' => true }

AND

def self.filter_marketdate(filter)
 case filter
  when 'monday' then monday.all
   else find(:all)
 end
end

In my show view for Markets, I have this:

<%= link_to_unless_current "All", :filter => 'all' %>
<%= link_to_unless_current "Mon", :filter => 'monday' %>    
   <% @market.schedules.each do |c| %>
     <%= link_to c.user.name, c.user %>
   <% end %>

Here's the weird part. The following is my log output when I select the Monday filter. If you look at the Select Schedules line of the output, you can see that the query is finding a limited number of user IDs. These are, in fact, the correct user IDs that I want to display for my filtered query. The part I don't understand is that after the app does the query perfectly, it then goes and loads all of the users instead of just the filtered results. I'm not sure what I'm missing.

Processing MarketsController#show (for ip at 2009-09-21 05:19:25) [GET]

  Parameters: {"id"=>"1", "filter"=>"monday"}

Market Load (0.8ms)   SELECT * FROM "markets" WHERE ("markets"."id" = 1) 

User Load (7.3ms)   SELECT "users".* FROM "users" INNER JOIN "schedules" ON "users".id = "schedules".user_id WHERE ((("schedules".market_id = 1)) AND ("schedules"."monday" = 't')) 

Schedule Load (4.3ms)   SELECT "schedules".* FROM "schedules" WHERE ("schedules".user_id IN (16,23,25,30,39,61,73,75,85,95,97,111,112,116,121,123,126,134,136,145,160,165,171,188,189)) 

Rendering template within layouts/application

Rendering markets/show
  Schedule Load (14.3ms)   SELECT * FROM "schedules" WHERE ("schedules".market_id = 1) 
  User Load (0.8ms)   SELECT * FROM "users" WHERE ("users"."id" = 2) 
  User Load (0.8ms)   SELECT * FROM "users" WHERE ("users"."id" = 8)

It goes on to list every user who is connected to this particular market, essentially doing a find.all.

UPDATE

In response to Brad's comment below, I tried changing the code in my markets/show view to the following, but I got the same result. I agree that the problem is in here somewhere, but I can't quite figure out how to solve it.

<%= link_to_unless_current "All", :filter => 'all' %>
<%= link_to_unless_current "Mon", :filter => 'monday' %>    
   <% @market.users.each do |user| %>
     <%= link_to user.name, user %>
   <% end %>
A: 

Shouldnt that be:

#Market.rb
has_many :users, :through => :schedules

Beside this, maybe this plugin helps you:

http://github.com/ntalbott/query%5Ftrace

It provides feedback for each sql statement and where it comes from..

f.e.:

Before:

  Schedule Load (0.023687)   SELECT * FROM schedules WHERE (schedules.id = 3) LIMIT 1
  Resource Load (0.001076)   SELECT * FROM resources WHERE (resources.id = 328) LIMIT 1
  Schedule Load (0.011488)   SELECT * FROM schedules WHERE (schedules.id = 3) LIMIT 1
  Resource Load (0.022471)   SELECT * FROM resources WHERE (resources.id = 328) LIMIT 1


After:

  Schedule Load (0.023687)   SELECT * FROM schedules WHERE (schedules.id = 3) LIMIT 1
    app/models/available_work.rb:50:in `study_method'
    app/helpers/plan_helper.rb:4:in `work_description'
    app/views/plan/_resource_schedule.rhtml:27:in `_run_rhtml_plan__resource_schedule'
    app/views/plan/_resource_schedule.rhtml:24:in `_run_rhtml_plan__resource_schedule'
    app/views/plan/_schedule_listing.rhtml:5:in `_run_rhtml_plan__schedule_listing'
    app/views/plan/_schedule_listing.rhtml:3:in `_run_rhtml_plan__schedule_listing'
    app/views/plan/_schedule_listing.rhtml:1:in `_run_rhtml_plan__schedule_listing'
    app/views/plan/index.rhtml:6:in `_run_rhtml_plan_index'
    vendor/plugins/textmate_footnotes/lib/textmate_footnotes.rb:60:in `render'
  Resource Load (0.001076)   SELECT * FROM resources WHERE (resources.id = 328) LIMIT 1
    app/models/available_work.rb:54:in `div_type'
    app/helpers/plan_helper.rb:6:in `work_description'
    app/views/plan/_resource_schedule.rhtml:27:in `_run_rhtml_plan__resource_schedule'
    app/views/plan/_resource_schedule.rhtml:24:in `_run_rhtml_plan__resource_schedule'
    app/views/plan/_schedule_listing.rhtml:5:in `_run_rhtml_plan__schedule_listing'
    app/views/plan/_schedule_listing.rhtml:3:in `_run_rhtml_plan__schedule_listing'
    app/views/plan/_schedule_listing.rhtml:1:in `_run_rhtml_plan__schedule_listing'
    app/views/plan/index.rhtml:6:in `_run_rhtml_plan_index'
    vendor/plugins/textmate_footnotes/lib/textmate_footnotes.rb:60:in `render'

UPDATE:

You have to call

<%= link_to_unless_current "All", :filter => 'all' %>
<%= link_to_unless_current "Mon", :filter => 'monday' %>    
   <% @users.each do |user| %>
     <%= link_to user.name, user %>
   <% end %>
Lichtamberg
Could you post your view-code of markets/show?
Lichtamberg
Added view code above.
MikeH
Like Brad said, you arent using the @user-variable
Lichtamberg
Look at my update
Lichtamberg
A: 

In your view, you are iterating over each market.schedule, not over the @users variable that you set. In fact, you aren't even using @users in the code you show us.

Brad
I added an update at the bottom of my question in response.
MikeH