具有“Has_many Through”关联的命名范围问题

时间:2009-09-21 09:23:29

标签: ruby-on-rails many-to-many associations modeling

我正在使用命名范围来处理一些过滤操作,并且日志显示一切都运行正常,除了在应用程序运行并找到正确的数据之后,它会忽略它找到的内容并且只列出一个查找。所有而不是过滤结果。这是详细信息。

我有3个型号:用户,市场和时间表。

用户has_many :schedules
用户has_many :markets, :through => :schedules

市场has_many :schedules
市场has_many :users, :through => :schedules

安排belongs_to :user 安排belongs_to :market

在每个市场的“显示”页面上,我显示在该市场上销售商品的用户。我还会显示这些用户在市场上的一周中的日子。该数据包含在连接模型中(即时间表)。

在市场页面上,我需要支持在用户进入市场的一周中过滤用户。

在我的市场控制器中,我有这个:

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

在我的市场模型中,我有这个:

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

在我的用户模型中,我有这个:

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

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

在我对市场的展示视图中,我有这个:

<%= 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 %>

这是奇怪的部分。当我选择星期一过滤器时,以下是我的日志输出。如果查看输出的“选择计划”行,则可以看到查询正在查找有限数量的用户标识。实际上,这些是我想要为我的过滤查询显示的正确用户ID。我不理解的部分是,在应用程序完美地执行查询之后,然后它会加载所有用户而不仅仅是过滤后的结果。我不确定我错过了什么。

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) 

它继续列出连接到这个特定市场的每个用户,主要是做一个find.all。

更新

为了回应下面的Brad的评论,我尝试将我的市场/展示视图中的代码更改为以下内容,但我得到了相同的结果。我同意问题就在这里,但我不知道如何解决它。

<%= 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 %>

2 个答案:

答案 0 :(得分:0)

不应该是:

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

除此之外,也许这个插件可以帮助你:

http://github.com/ntalbott/query_trace

它为每个sql语句及其来源提供反馈..

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'

<强>更新

你必须致电

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

答案 1 :(得分:0)

在您看来,您正在遍历每个market.schedule,而不是遍历您设置的@users变量。事实上,你甚至没有在你向我们展示的代码中使用@users。