“Has Many Through”的命名范围问题协会

发布于 2024-08-05 11:55:34 字数 2941 浏览 2 评论 0原文

我正在使用命名范围来处理一些过滤操作,日志显示一切工作正常,除了应用程序找到正确的数据后,它会忽略找到的内容并仅列出 find.all 而不是过滤后的结果。详细信息如下。

我有 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 %>

这是奇怪的部分。以下是我选择星期一过滤器时的日志输出。如果查看输出的 Select Schedules 行,您可以看到查询正在查找有限数量的用户 ID。事实上,这些是我想要为过滤查询显示的正确用户 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。

更新

为了回应下面布拉德的评论,我尝试将我的市场/显示视图中的代码更改为以下内容,但我得到了相同的结果。我同意问题就在这里某个地方,但我不太清楚如何解决它。

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嗫嚅 2024-08-12 11:55:34

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

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.

晨敛清荷 2024-08-12 11:55:34

不应该是:

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

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

http://github.com/ntalbott/query_trace

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

fe:

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

Shouldnt that be:

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

Beside this, maybe this plugin helps you:

http://github.com/ntalbott/query_trace

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 %>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文