Reputation: 32162
If I have the following classes
class User
has_many :documents
end
class Document
belongs_to :user
end
I would like to be able to do the following
User.where("id > 200").documents
which should generate SQL like
select * from documents
join users on documents.user_id == users.id
where users.id > 200
but activerecord is not that clever. Is this an unreasonable thing to expect to be possible out of the box?
== A possible anti DRY solution ==
class User
has_many :documents
def self.documents
Documents.joins(:users).merge(self.scoped)
end
end
but this is not very DRY as it seems to replicate the relations I have already defined.
Upvotes: 0
Views: 204
Reputation: 114178
For your example classes you can just query the user_id
field in the documents
table:
Document.where("user_id > 200")
Upvotes: 0
Reputation: 1761
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 :)
Upvotes: 1