Rails:在Model的Class方法中迭代集合

时间:2016-11-02 20:47:47

标签: ruby-on-rails ruby activerecord rails-activerecord

我有一组Foo个对象。我想创建一个迭代该集合的类方法,如果该集合中的所有对象都具有某个属性的特定值,则返回true。否则,类方法返回false

我尝试了以下操作,但它不起作用:

class Foo < ActiveRecord::Base

  def self.all_have_number_value_999?
    each do |foo_object|
      return false if foo_object.number_val != 999
    end
    return true #all objects have #number_val == 999
  end

end

现在假设我以某种方式收集了Foo个对象。我将了解如何获得Foo对象的集合,但重要的是number_value_999?可以遍历该集合。换句话说:一些未知范围预先生成了Foo个对象的集合。我只想在一个Foo类方法中迭代该集合

Foo.where(id: [123, 456]).all_have_number_value_999?

它在类方法中抱怨,因为它不知道如何迭代集合。这就是我的问题:如何在模型的类方法中迭代集合?

1 个答案:

答案 0 :(得分:2)

逆转你的逻辑,让数据库完成工作。如果他们都有number_val 999,则他们都没有number_val 999,这很容易表达:< / p>

def self.all_have_number_value_999
  !where.not(:number_val => 999).exists?
end

这将是一个相当有效的数据库查询。

由于这是一个类方法,并且类方法被混合到关系中(范围毕竟是类方法的几乎特定类型),您可以在关系和类似的事情上调用此方法:

Foo.where(id: [123, 456]).all_have_number_value_999?

应该像Foo.all_have_number_value_999?一样工作。

如果要在迭代数据库外部的集合时执行一些任意逻辑,那么您可以在迭代之前抛出all调用来解析查询:

def self.all_have_number_value_999?
  all.each do |foo_object|
    ...
  end
end