ruby-on-rails - Rails belongs_to has_many 与数据库条件

标签 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

我需要的是将两者在 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 "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/

相关文章:

ruby-on-rails - rails : link_to with block and GET params?

mysql - Rails+ActiveRecords : How to group records by date and show their count based on a condition?

android - 从 Sqlite 数据库表中删除时出现故障(关系异常行为)

Rails 中的 CSS 命名空间

php - 父对象初始化后初始化相关对象

ruby-on-rails - 我是否需要在此测试中创建每个对象?

r - 我怎样才能得到一个按谱系相互关联的值(value)指数列表? [R]

laravel 4 关系 - 如何显示用户投票记录的前 5 名排名

ruby-on-rails - Rails/Bootstrap - Flash 通知 :success is now red and not green?

ruby-on-rails - 在rails中需要一个gem