0

如果我有以下课程

class User
    has_many :documents
end

class Document
    belongs_to :user
end

我希望能够做到以下几点

User.where("id > 200").documents

应该生成类似的 SQL

select * from documents
join users on documents.user_id == users.id
where users.id > 200

但是activerecord并不是那么聪明。期望开箱即用是一件不合理的事情吗?

== 一个可能的抗 DRY 解决方案 ==

class User
    has_many :documents
    def self.documents
        Documents.joins(:users).merge(self.scoped)
    end
end

但这不是很干,因为它似乎复制了我已经定义的关系。

4

3 回答 3

1

No you can't do that with ActiveRecord. Rule of thumb - the class you start calling methods on, is the one that the returning objects are. So doing User.whatever will always return User objects. This pretty much eliminates the possibility to do what you want.

If you want to get Document objects, you need to start querying for them on the Document class instead. You could always define you user specific scopes in the User model and reuse them in your Document model for the sake of 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

This effectively lets you use the scope defined in User (and which is user specific) in your Document model. I would also claim in that User.where("id > 200").documents makes less sense than Document.where("users.id > 200") (join skipped intentionally).

So I personally think you are just trying to approach this issue from the wrong end :)

于 2012-07-03T07:28:23.627 回答
0

尝试这个:

Document.joins(:user).where('user.id > ?', 200)
于 2012-07-03T06:59:49.687 回答
0

对于您的示例类,您只需查询 表user_id中的字段documents

Document.where("user_id > 200")
于 2012-07-03T07:38:57.233 回答