Rafael Costa
Rafael Costa

Reputation: 1471

Rails, override association method

Well, I have a model with a has_many association:

class Foo < ApplicationRecord
  has_many :bars
end

Now, I know that if I call foo.bars it loads all the bars where foo_id is foo.id, right? But I would like to override it, so that I could load bars based on other params..

This answer kinda teaches how to override the << (value) method. But yet, I don't know how to apply it in my case.

How could I do that?? Something like this:

class Foo < ApplicationRecord
  has_many :bars do
    def bars
      self.owner = Bar.where(date: foo.date) #just an example
    end
  end
end

???

Upvotes: 0

Views: 1098

Answers (2)

Ryan Lue
Ryan Lue

Reputation: 987

It sounds like you're asking for a way to override an association getter so that it acts like a simple scope or where query instead — namely, that you want foo.bars to return a set of bars that may or may not belong to foo.

This is a huge red flag.

The whole point of having the #bars association getter method as an instance method of Foo is to return a list of bars related to a single model object. If you want something different, define the behavior somewhere else.

In theory, what you're asking is possible — just take the def bars stanza from your example out of the has_many block and put it on the same level as all your other method definitions. But there's simply no sense in it.

Bar.where and scope are built to do what you're asking about. If you don't want to limit your query to a given Foo, then leave Foo out of it.

Upvotes: 0

Eyeslandic
Eyeslandic

Reputation: 14890

You can set a condition on the has_many attribute like this

has_many :bars, -> { where(active: true) } 

More on that in the guides (section 4.3.3)

Upvotes: 3

Related Questions