Rails belongs_to has_many与db条件

时间:2014-03-18 16:55:47

标签: ruby-on-rails activerecord relationship rails-activerecord

我有两个型号,让我们说:

Post:
  blog_id: integer
  external_id: integer

Comment:
  blog_id: integer
  external_reference_id: integer

我的数据库中有一些项目:

Post.create external_id: 10, title: "Test 1", blog_id: 1
Post.create external_id: 10, title: "Test 2", blog_id: 2
Post.create external_id: 10, title: "Test 3", blog_id: 3

Comment.create external_reference_id: 10, title: "Comment 1.1", blog_id: 1
Comment.create external_reference_id: 10, title: "Comment 1.2", blog_id: 1

Comment.create external_reference_id: 10, title: "Comment 2.1", blog_id: 2
Comment.create external_reference_id: 10, title: "Comment 2.2", blog_id: 2

我需要使用external_引用来关联帖子和评论,即:

class Post < ActiveRecord::Base
    has_many :comments, foreign_key: :external_reference_id, primary_key: :external_id
end

class Comments < ActiveRecord::Base
    belongs_to :post, foreign_key: :external_reference_id, primary_key: :external_id
end

我需要的是&#34;范围&#34; blog_id上两者之间的关系是一样的。

我的意思是我在不同的服务器/数据库上有不同的博客,我收集主服务器中的所有数据。我无法保留原始ID,因此我将id存储为external_id。这意味着包含external_id: 1blog_id: 4的帖子将包含external_reference_id: 1blog_id: 4的所有评论。

我可能会对同一个external_id发表很多评论,但只有同一个blog_id真的匹配。

上网时,我发现了一些提示,最流行的意见是这样的:

class Post < ActiveRecord::Base
  has_many :comments, -> (object){ where("comments.blog_id = #{object.blog_id}") }, foreign_key: :external_reference_id, primary_key: :external_id
end

此解决方案在执行Post.first.comments时正确生成查询:

SELECT COUNT(*)FROM&#34; comments&#34;在哪里&#34;评论&#34;。&#34; external_reference_id&#34; =? AND(comments.blog_id = 1)[[&#34; external_reference_id&#34;,10]]

但是当他尝试更像Post.joins(:comments).count给出更深奥的东西时,它却惨遭失败:

NoMethodError: undefined method `blog_id' for #<ActiveRecord::Associations::JoinDependency::JoinAssociation

到目前为止我的解决方案是:

class Post < ActiveRecord::Base
  has_many :comments, -> (object){ where(object.respond_to?(:blog_id) ? "comments.blog_id = #{object.blog_id}" : 'comments.blog_id = posts.blog_id') }, foreign_key: :external_reference_id, primary_key: :external_id
end

哪种方法很好,但在我看来看起来有点过于复杂。有没有更好的方法来实现这一目标?

1 个答案:

答案 0 :(得分:0)

您可以为has_many和belongs_to添加:条件,例如

class Post < ActiveRecord::Base
  has_many :comments, foreign_key: :external_reference_id, primary_key: :external_id, :conditions => ["comments.blog_id = posts.blog_id"]
end

class Comments < ActiveRecord::Base
  belongs_to :post, foreign_key: :external_reference_id, primary_key: :external_id, :conditions => ["comments.blog_id = posts.blog_id"]
end 

我没有对此进行过测试,但试一试。