向对象的 Activerecord 关系添加方法

Add a method to an Object's ActiverecordRelation

我有一个模型 SchoolPerformanceStatshas_many 关系。

我发现自己经常在控制台和一些 rake 任务中编写这段代码。

School.where(city: "Chicago").joins(:performance_stats).where(performance_stats: {year: "1819"}.where.not(performance_stats: {gr3_score: nil})

虽然我也许可以通过在学校的 ActiveRecord 关系中包含一个方法来缩短它,所以我可以做类似的事情:

School.where(city: "Chicago").pstatjoin("1819","gr_score",nil)

def pstatjoin(year,x,y)
 x.to_sym
 self.joins(:performance_stats).where(performance_stats: {year: year}.where.not(performance_stats: {x => y})
end

但我不确定将此代码放在哪里。

我在 SchoolsHelper 模块中试过这个:

Module SchoolHelper
  Class School
    def pstatjoin(year,x,y)
     x = x.to_sym
     self.joins(:performance_stats).where(performance_stats: {year: year}.where.not(performance_stats: {x => y})
    end
  end
end

并且我将模块包含在学校模型中

include SchoolsHelper

但这导致 undefined method 'pj' for #<School::ActiveRecord_Relation:hexidecimal>)

有没有办法在不添加适用于每个 ActiveRecord_Relation 的代码的情况下执行此操作?

我觉得approach/fit这个问题的好办法肯定是scopes,有了scope可以节省一些时间并且遵守DRY原则,所以你可以在你的[=内定义一个scope 12=]型号如下:

scope :my_awesome_scope, ->(year, x, y) {joins(:performance_stats).where(performance_stats: {year: year}.where.not(x => y)}

然后你就可以像下面这样在任何地方使用它了:

School.my_awesome_scope(year, x.to_sym, y)

甚至:School.where(...).my_awesome_scope(year, x.to_sym, y)

希望对您有所帮助!