我有两个模型,比方说:
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
我需要的是将两者在 blog_id 上的关系“限定”为相同。
我的意思是我在不同的服务器/数据库上有不同的博客,并且我正在主服务器中收集所有数据。我无法保留原始 ID,因此我将 id 存储为 external_id。这意味着带有 external_id: 1
和 blog_id: 4
的帖子将包含所有带有 external_reference_id: 1
和 blog_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 "comments"WHERE "comments"."external_reference_id"= ? AND (comments.blog_id = 1) [["external_reference_id", 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
效果很好,但在我看来有点过于复杂。有没有更好的方法来实现这一点?
最佳答案
你可以在 has_many 和 belongs_to 中添加 :conditions,例如
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
我还没有测试过,但试一试。
关于ruby-on-rails - Rails belongs_to has_many 与数据库条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22485997/