Reputation: 2485
I have a model A that has many of another model B, which has_many of a third model C, and want to delegate A from B to C. For example:
class House < ApplicationRecord
has_many :pets
end
class Pet < ApplicationRecord
belongs_to :house
has_many :toys
delegate :house, to: :toys
end
class Toy < ApplicationRecord
belongs_to :pet
end
> toy.house
As it stands, I have to use toy.pet.house
Upvotes: 2
Views: 1721
Reputation: 12643
You can use the :through
option on your ActiveRecord associations to accomplish what you want. Configure your models as follows:
class House < ApplicationRecord
has_many :pets
has_many :toys, through: :pets
end
class Pet < ApplicationRecord
belongs_to :house
has_many :toys
end
class Toy < ApplicationRecord
belongs_to :pet
has_one :house, through: :pet
end
Here is a link to the official guide for the :through option on has_many and has_one associations.
Upvotes: 0
Reputation: 20253
Try
class Toy < ApplicationRecord
belongs_to :pet
delegate :house, to: :pet
end
And remove
delegate :house, to: :toys
from Pet
.
There are at least two problems with:
class Pet < ApplicationRecord
belongs_to :house
has_many :toys
delegate :house, to: :toys
end
First, an instance of Toy
doesn't respond to house
, so you can't delegate :house, to: :toys
. Second, even if an instance of Toy
did respond to house
, you wouldn't be able to call that instance method on a collection, which is what toys
is. So, that's busted all over the place.
Pet
, however, does respond to house
. And, Toy belongs_to :pet
. So, you do Toy delegate :house, to: :pet
. And Bob's your uncle!
Upvotes: 4