has_many :through with :primary_key 在连接表上不起作用
在我的 Rails 3 项目中,我有一个通过以下模型进行自引用连接的用户模型。我想使用此连接表来查找与关注的用户相关的活动。我几乎所有设置都正确,除了连接生成的查询完全忽略连接模型上的 :primary_key 选项。
这是相关模型的相关架构:
create_table "users", :force => true do |t|
t.string "email", :default => "", :null => false
t.string "first_name"
t.string "last_name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "follows", :force => true do |t|
t.integer "user_id"
t.integer "followed_user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "activities", :force => true do |t|
t.integer "user_id"
t.text "body"
t.datetime "created_at"
t.datetime "updated_at"
end
这是模型中的关联
class User < ActiveRecord::Base
has_many :follows
has_many :followed_users, :through => :follows
has_many :followed_activities, :through => :follows
has_many :activities
end
class Follow < ActiveRecord::Base
belongs_to :user
belongs_to :followed_user, :class_name => "User"
has_many :followed_activities, :primary_key => :followed_user, :foreign_key => :user_id, :class_name => "Activity"
end
以下工作正常:
u = User.first
u.follows # returns corresponding records from the follows table
u.followed_users # returns all users that u is following
u.followed_users.first.activities # returns all activity records corresponding to the first person the user is following
Follow.first.activities # same as the previous
但是,以下仅返回一个空数组:
u.followed_activities
这是从最后一条语句生成的 sql:
Activity Load (0.2ms) SELECT `activities`.* FROM `activities` INNER JOIN `follows` ON `activities`.user_id = `follows`.id WHERE ((`follows`.user_id = 1))
原因不是工作是因为它试图加入使用 'follows'.id 作为主键而不是 'follows'.followed_user。
这是一个错误,还是我必须在用户模型的某处重复 :primary_key 声明?我在 Rails api 或在线其他任何地方都找不到任何提及。
导轨版本:3.0.7
In my Rails 3 project, I have a user model with a self referential join, through the follow model. I want to use this join table to find activity related to the followed user. I have almost everything set up correctly, except that the query generated by the join is totally ignoring the :primary_key option on the join model.
Here is the relevant schema for the relevant models:
create_table "users", :force => true do |t|
t.string "email", :default => "", :null => false
t.string "first_name"
t.string "last_name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "follows", :force => true do |t|
t.integer "user_id"
t.integer "followed_user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "activities", :force => true do |t|
t.integer "user_id"
t.text "body"
t.datetime "created_at"
t.datetime "updated_at"
end
Here's the associations in the models
class User < ActiveRecord::Base
has_many :follows
has_many :followed_users, :through => :follows
has_many :followed_activities, :through => :follows
has_many :activities
end
class Follow < ActiveRecord::Base
belongs_to :user
belongs_to :followed_user, :class_name => "User"
has_many :followed_activities, :primary_key => :followed_user, :foreign_key => :user_id, :class_name => "Activity"
end
The following work just fine:
u = User.first
u.follows # returns corresponding records from the follows table
u.followed_users # returns all users that u is following
u.followed_users.first.activities # returns all activity records corresponding to the first person the user is following
Follow.first.activities # same as the previous
However, the following just returns an empty array:
u.followed_activities
Here is the sql that is generated from the last statement:
Activity Load (0.2ms) SELECT `activities`.* FROM `activities` INNER JOIN `follows` ON `activities`.user_id = `follows`.id WHERE ((`follows`.user_id = 1))
The reason it isn't working is because it is trying to join use 'follows'.id as the primary key rather than 'follows'.followed_user.
Is this a bug, or do I have to repeat the :primary_key declaration somewhere on the user model? I can't find any mention anywhere in the Rails api, or anywhere else online.
Rails Version: 3.0.7
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Justin,您有 2 个名为“followed_activities”的关联。当然,它们有不同的上下文(不同的模型),但我想请您尝试关联块内的方法,如下所示:
Justin, you have 2 associations called "followed_activities". sure, they have different context (different models), but I'd like to ask you to try method inside the association block like this:
我发现与“nested_has_many_through”gem 的菊花链关系很直观, http://rubygems.org/gems/ nested_has_many_through 这将是 Rails 3.1 的标准部分,可以为您提供另一种工具来解决这里的问题
它会让您做这样的事情:
这极大地简化了我的查询和集合。我希望你能找到问题的答案,这是一个很难的问题!
I've found it intuitive to daisy chain relationships with the 'nested_has_many_through' gem, http://rubygems.org/gems/nested_has_many_through which will be a standard part of rails 3.1 and could give you another tool to tackle the issue here
It will let you do something like this:
This has super-simplified my queries and collections. I hope you find an answer to your problem, it's a tough one!