将一个对象数组转换为ActiveRecord :: Relation
我有一个对象的数组,我们称之为Indicator
。 我想在这个数组上运行Indicator类的方法(那些def self.subjects
变种,作用域等等)。 我知道在一组对象上运行类方法的唯一方法是让它们成为ActiveRecord :: Relation。 所以我最终诉诸添加to_indicators
方法到Array
。
def to_indicators # TODO: Make this less terrible. Indicator.where id: self.pluck(:id) end
有时我链接了相当多的这些范围来筛选结果,在类方法中。 所以,即使我调用一个ActiveRecord :: Relation方法,我不知道如何访问该对象。 我只能通过all
的内容来了解它的内容。 但是all
都是一个数组。 那么我必须将该数组转换为ActiveRecord :: Relation。 例如,这是其中一种方法的一部分:
all.to_indicators.applicable_for_bank(id).each do |indicator| total += indicator.residual_risk_for(id) indicator_count += 1 if indicator.completed_by?(id) end
我想这可以归结为两个问题。
- 如何将一个对象数组转换为一个ActiveRecord :: Relation? 最好不要每次都做一次。
- 在ActiveRecord :: Relation上运行
def self.subjects
types方法时,如何访问ActiveRecord :: Relation对象本身?
谢谢。 如果我需要澄清任何事情,请告诉我。
如何将一个对象数组转换为一个ActiveRecord :: Relation? 最好不要每次都做一次。
你不能将一个数组转换成一个ActiveRecord :: Relation,因为一个Relation只是一个SQL查询的构build器,而且它的方法不能对实际数据进行操作。
但是,如果你想要的是一个关系,那么:
-
对于ActiveRecord 3.x,不要调用
all
,而是调用scoped
,这将返回一个关系,它代表了all
将在一个数组中给你的相同的logging。 -
为ActiveRecord 4.x,只需调用
all
,这将返回一个关系。
在ActiveRecord :: Relation上运行
def self.subjects
types方法时,如何访问ActiveRecord :: Relation对象本身?
在Relation对象上调用该方法时, self
就是关系(与其定义的模型类相反)。
你可以把一个对象数组arr
转换成这样的ActiveRecord :: Relation(假设你知道哪个类是对象,你可能会这样做)
MyModel.where(id: arr.map(&:id))
你必须使用where
但它是一个有用的工具,你不应该不愿意使用。 现在你有一个单线程转换数组到一个关系。
map(&:id)
将把你的对象数组转换为只包含它们的id的数组。 将一个数组传递给where子句将会生成一个IN
语句的SQL语句,如下所示:
SELECT .... WHERE `my_models`.id IN (2, 3, 4, 6, ....
请记住,数组的sorting会丢失 – 但是因为你的目标只是在这些对象的集合上运行一个类方法,所以我认为这不会是一个问题。
那么,就我而言,我需要将一个对象数组转换为ActiveRecord :: Relation ,并将其sorting为一个特定的列(例如id)。 由于我正在使用MySQL, 字段function可能会有所帮助。
MyModel.where('id in (?)',ids).order("field(id,#{ids.join(",")})")
SQL看起来像:
SELECT ... FROM ... WHERE (id in (11,5,6,7,8,9,10)) ORDER BY field(id,11,5,6,7,8,9,10)
MySQL字段function
为什么不把你的对象存储在一个空的ActiveRecord :: Relation中,这样你就可以访问它们。 像这样
collection = MyModel.where(attribute: nil) #=> #<ActiveRecord::Relation []>
注意:只要确保你只返回一个空的活动logging关系。 您可以将对象存储在集合中,并将其视为活动logging对象的常规集合,而不必执行涉及将对象数组转换为活动logging关系的杂技。 你可以在你的rails控制台中testing这个。 它为我工作。 我知道这是一个黑客,但我目前还没有意识到一个ruby的方式分配一个空的活动logging关系的variables。