A user can have several cars -
User: has_many :cars
Car: belongs_to :user
Every time I call @user.cars
it returns the list of cars
in default search order.
If I wanted the association sorted on some arbitrary field, I could do
class User < ActiveRecord::Base
has_many :cars, -> { order :num_wheels }
end
But let's say my ordering logic is complex and I want to just override the association getter to implement my own logic
I try something something like -
class User < ActiveRecord::Base
has_many :cars
def cars
# Pretend this is complex logic
cars.order(:num_wheels)
end
end
However that obviously fails because you can't reference the original cars
from inside the overridden cars
method without it looping infinitely.
Is there a way to reference the "original" getter from inside my overridden getter?
Thanks!
Use super:
class User < ActiveRecord::Base
has_many :cars
def cars
# Pretend this is complex logic
super.order(:num_wheels)
end
end
when you use a macro like has_many, Rails dynamically creates a module(which could be accessed by User.generated_association_methods).In your case, define the accessors and readers(such as "cars" in your case, which could be accessed by User.generated_association_methods.instance_methods). This module becomes the ancestor of your User class, so you can access the reader method(cars) by "super" in your own cars method.
With my understanding I believe what has_many is essentially doing is:
Class User < ActiveRecord::Base
has_many :cars
# is essentially
def cars
Car.where(user_id: self.id)
end
end
So when a user wants to list all the cars it would still be User.cars. When using ActiveRecord the has_many is assuming both the method name of cars and the foreign keys associated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With