如果我有以下类
class User
has_many :documents
end
class Document
belongs_to :user
end
我希望能够执行以下操作
User.where("id > 200").documents
应该生成类似 SQL 的 SQL
select * from documents
join users on documents.user_id == users.id
where users.id > 200
但ActiveRecord并没有那么聪明。这是一件不合理的事情,期望开箱即用吗?
== 可能的抗干燥解决方案 ==
class User
has_many :documents
def self.documents
Documents.joins(:users).merge(self.scoped)
end
end
但这不是很干燥,因为它似乎复制了我之间的关系已经定义。
不,你不能用ActiveRecord做到这一点。经验法则 - 您开始调用方法的类是返回对象的类。所以做 User.what 将始终返回 User 对象。这几乎消除了做你想做的事的可能性。
如果要获取 Document 对象,则需要改为在 Document 类上开始查询它们。您始终可以在用户模型中定义用户特定的范围,并在文档模型中重用它们以实现 DRY。
class User < ActiveRecord::Base
scope :foo, where("users.id > 200")
end
class Document < ActiveRecord::Base
belongs_to :user
scope :bar, joins(:user).merge(User.foo)
end
这有效地允许您在文档模型中使用用户中定义的范围(以及特定于用户的范围)。我还声称User.where("id> 200").documents比Document.where("users.id> 200")更有意义(故意跳过加入)。
所以我个人认为你只是试图从错误的一端处理这个问题:)
试试这个:
Document.joins(:user).where('user.id > ?', 200)
对于示例类,您只需查询documents
表中的user_id
字段:
Document.where("user_id > 200")