关联问题

时间:2010-12-02 04:23:01

标签: ruby-on-rails ruby model associations

我在rails应用程序上构建了一个ruby,可以让用户跟踪他们的锻炼情况。用户has_many锻炼。此外,如果用户是健身房所有者,则可以创建一个盒子(健身房)。目的是过滤用户的活动,使他们只能看到与健身房相关的信息。在这种情况下锻炼。在框显示页面上...我想通过成员资格显示与该框相关联的所有用户,然后显示相关用户的锻炼。这是设置。

用户

class User < ActiveRecord::Base
  has_many :boxes
  has_many :workouts, :dependent => :destroy
end

锻炼

class Workout < ActiveRecord::Base
  belongs_to :user
  belongs_to :box
end

class Box < ActiveRecord::Base
  belongs_to :user
  has_many :users, :through => :memberships
  has_many :workouts, :through => :users
  has_many :memberships
end

成员

class Membership < ActiveRecord::Base
  belongs_to :user
  belongs_to :box
end

在我的/views/boxes/show.html.erb视图中,我有以下内容:

<% @box.workouts.each do |workout| %>
  <%= workout.title %><br/>
  <%= workout.user.username %><br/><br/>
<% end %>

没有产生错误......但没有结果。这是日志的输出

Processing BoxesController#show (for 127.0.0.1 at 2010-12-01 22:19:59) [GET]
  Parameters: {"id"=>"7"}
  User Load (0.4ms)   SELECT * FROM "users" WHERE ("users"."id" = '1') LIMIT 1
  Box Load (0.3ms)   SELECT * FROM "boxes" WHERE ("boxes"."id" = 7) 
  CACHE (0.0ms)   SELECT * FROM "boxes" WHERE ("boxes"."id" = 7) 
  User Load (0.4ms)   SELECT * FROM "users" WHERE ("users"."id" = 1) 
  Workout Load (0.3ms)   SELECT "workouts".* FROM "workouts" INNER JOIN "users" ON "users".id = "workouts".user_id INNER JOIN "boxes" ON "boxes".id = "workouts".box_id WHERE ("workouts"."user_id" = 1) AND ((("workouts"."public" = 1) AND (("users".box_id = 7))) AND (("users".box_id = 7))) ORDER BY created_at DESC
Rendering template within layouts/application
Rendering boxes/show
  User Load (0.6ms)   SELECT "users".* FROM "users" INNER JOIN "memberships" ON "users".id = "memberships".user_id WHERE (("memberships".box_id = 7)) 
  Workout Load (0.2ms)   SELECT "workouts".* FROM "workouts" INNER JOIN "users" ON "workouts".user_id = "users".id WHERE (("users".box_id = 7)) 
Rendered shared/_navigation (0.6ms)
Completed in 104ms (View: 23, DB: 2) | 200 OK [http://localhost/boxes/7]

为什么这不起作用的想法?

1 个答案:

答案 0 :(得分:2)

我认为问题在于,用户成员资格与协方框的关联与您之前尝试过的内容混在一起。因为如果您查看最后一次在日志中加载Workout:

Workout Load (0.2ms)   
SELECT "workouts".* 
FROM "workouts" 
INNER JOIN "users" ON "workouts".user_id = "users".id 
WHERE (("users".box_id = 7))

WHERE条件表示用户属于我无法从您的代码中看到的框。并且由于您没有从该行获得任何错误,该字段必须存在于数据库中,您应该删除它。

此外,您已指定用户has_many框,但似乎您忘记添加它是通过:成员资格。我想正确的方法是:

class User < ActiveRecord::Base
  has_many :memberships
  has_many :boxes, :through => :memberships
  has_many :workouts, :dependent => :destroy
end

最后,通过关联组合两个将无法工作,至少在此设置中不起作用。如果您希望在特定的框中为用户进行所有锻炼,那么您可以执行以下操作:

#In Controller
@box_users = @box.users.all(:include => :workouts)

#In View
<% @box_users.each do |user| %>
  <% user.workouts.each do |workout| %>
    <%= workout.title %>
    <%= user.username %>
  <% end %>
<% end %>

调用:include当然不是必需的,但它会生成一个sql查询而不是1 + n