覆盖has_many关联getter

use*_*003 6 activerecord ruby-on-rails

用户可以拥有多辆车 -

  • User: has_many :cars
  • Car: belongs_to :user

每次调用@user.cars它都会返回cars默认搜索顺序列表.

如果我希望关联在某个任意字段上排序,我可以做到

class User < ActiveRecord::Base
  has_many :cars, -> { order :num_wheels }
end
Run Code Online (Sandbox Code Playgroud)

但是,假设我的排序逻辑很复杂,我想重写关联getter来实现我自己的逻辑

我尝试了类似的东西 -

class User < ActiveRecord::Base
  has_many :cars

  def cars
    # Pretend this is complex logic
    cars.order(:num_wheels)
  end
end
Run Code Online (Sandbox Code Playgroud)

然而,这显然是失败的,因为你无法cars在被覆盖的cars方法中引用原始而没有无限循环.

有没有办法从我被覆盖的吸气剂中引用"原始"吸气剂?

谢谢!

lei*_*liu 13

使用超级:

class User < ActiveRecord::Base
  has_many :cars

  def cars
    # Pretend this is complex logic
    super.order(:num_wheels)
  end
end
Run Code Online (Sandbox Code Playgroud)

当您使用像has_many这样的宏时,Rails会动态创建一个模块(可以通过User.generated_association_methods访问).在您的情况下,定义访问者和读者(例如您的案例中的"汽车",可以由用户访问). generated_association_methods.instance_methods).此模块成为User类的祖先,因此您可以通过自己的汽车方法中的"super"访问读取器方法(汽车).