has_many:通过:连接表上的primary_key不起作用

时间:2011-07-16 02:20:29

标签: ruby-on-rails activerecord join primary-key has-many-through

在我的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))

它不起作用的原因是因为它试图加入使用'follow'.id作为主键而不是'follow'.followed_user。

这是一个错误,还是我必须在用户模型的某处重复:primary_key声明?我无法在Rails api或其他任何网络上找到任何提及。

Rails版本:3.0.7

2 个答案:

答案 0 :(得分:1)

我发现使用'nested_has_many_through'gem,http://rubygems.org/gems/nested_has_many_through的菊花链关系是直观的,这将是rails 3.1的标准部分,并且可以为您提供另一个解决此问题的工具

它会让你做这样的事情:

class Author < User
  has_many :posts
  has_many :categories, :through => :posts, :uniq => true
  has_many :similar_posts, :through => :categories, :source => :posts
  has_many :similar_authors, :through => :similar_posts, :source => :author, :uniq => true
  has_many :posts_of_similar_authors, :through => :similar_authors, :source => :posts, :uniq => true
  has_many :commenters, :through => :posts, :uniq => true
end

class Post < ActiveRecord::Base
  belongs_to :author
  belongs_to :category
  has_many :comments
  has_many :commenters, :through => :comments, :source => :user, :uniq => true
end

这极大地简化了我的查询和集合。我希望你找到问题的答案,这是一个艰难的问题!

答案 1 :(得分:0)

贾斯汀,你有2个叫做“follow_activities”的联想。当然,他们有不同的上下文(不同的模型),但我想请你在这样的关联块内尝试方法:

has_many :followed_users, :through => :follows do
  def activities
  end
end