在 Ruby 中,如果给定 N 个参数,如何编写一个链接命名范围 N 次的可链接方法

in Ruby, how write a chainable method that chains a named scope N times if given N parameters

我有一个命名范围 :name_not_like 如果 :name 匹配模式

,它会忽略关系中的记录
scope :name_not_like, lambda { |n| where('name NOT ILIKE ?', n) }

我有一个方法可以省略所有的汤姆、迪克和哈利:

def self.except_tom_dick_harry
  name_not_like("%tom%").name_not_like("%dick%").name_not_like("%harry%")
end

如何编写一个方法 except_these_names() 给定一个包含 N 个名称的数组将链接 name_not_like() N 次,以便

except_these_names(["%tom%", "%dick%", "%harry%", "%sam%", "%fred%"]) 会做与 except_tom_dick_harry() 相同的事情,但对于数组中的所有名称?像这样:

def self.except_these_names(array_of_names)
  array_of_names.each do |name|
    # somehow 'stack' calls to name_not_like(name) ??
  end
end

我认为像这样的东西应该有用。 reduce 非常适合需要在以前的结果基础上积累的情况。

def self.except_these_names(names)
  names.reduce(scoped) do |criteria, name|
    criteria.name_not_like("%#{name}%")
  end
end

或者实际上,您可以使用简单的 each。只需将 criteria var 放在循环之外。

def self.except_these_names(array_of_names)
  criteria = scoped
  array_of_names.each do |name|
    criteria = criteria.name_not_like(...)
  end

  criteria
end