bradgonesurfing
bradgonesurfing

Reputation: 32162

Using associations like scopes

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

Answers (3)

Stefan
Stefan

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

Tanel Suurhans
Tanel Suurhans

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

xdazz
xdazz

Reputation: 160833

Try this:

Document.joins(:user).where('user.id > ?', 200)

Upvotes: 0

Related Questions