Nat*_*han 93 ruby activerecord ruby-on-rails
我有一个对象数组,我们称之为Indicator.我想def self.subjects在这个数组上运行Indicator类方法(变种类,范围等).我知道在一组对象上运行类方法的唯一方法是让它们成为ActiveRecord :: Relation.所以我最终要求添加一个to_indicators方法Array.
def to_indicators
# TODO: Make this less terrible.
Indicator.where id: self.pluck(:id)
end
Run Code Online (Sandbox Code Playgroud)
有时我会链接相当多的这些范围来过滤类方法中的结果.所以,即使我在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
Run Code Online (Sandbox Code Playgroud)
我想这可以归结为两个问题.
where每次都做.def self.subjectsActiveRecord :: Relation上运行类型方法时,如何访问ActiveRecord :: Relation对象本身?谢谢.如果我需要澄清任何事情,请告诉我.
Mar*_*ins 152
你可以arr像这样将一个对象数组转换为一个ActiveRecord :: Relation(假设你知道对象是哪个类,你可能会这样做)
MyModel.where(id: arr.map(&:id))
Run Code Online (Sandbox Code Playgroud)
你必须使用where它,它是一个你不应该不愿意使用的有用工具.现在你有一个单行程序将数组转换为关系.
map(&:id)将您的对象数组转换为仅包含其ID的数组.将数组传递给where子句将生成一个SQL语句,IN其外观如下所示:
SELECT .... WHERE `my_models`.id IN (2, 3, 4, 6, ....
Run Code Online (Sandbox Code Playgroud)
请记住,数组的顺序将丢失 - 但由于您的目标只是在这些对象的集合上运行类方法,我认为它不会是一个问题.
And*_*all 44
如何将对象数组转换为ActiveRecord :: Relation?最好不要每次都做一次.
您无法将Array转换为ActiveRecord :: Relation,因为Relation只是SQL查询的构建器,并且其方法不能对实际数据进行操作.
但是,如果你想要的是一个关系,那么:
对于ActiveRecord 3.x,不要调用all而是调用scoped,这将返回一个Relation,它表示all将在Array中提供的相同记录.
对于ActiveRecord 4.x,只需调用all,返回一个Relation.
在
def self.subjectsActiveRecord :: Relation上运行类型方法时,如何访问ActiveRecord :: Relation对象本身?
在Relation对象上调用方法时,self是关系(与其定义的模型类相对).
好吧,以我为例,我需要将对象数组转换为ActiveRecord :: Relation并使用特定的列(例如,id)对它们进行排序。由于我使用的是MySQL,因此field函数可能会有所帮助。
MyModel.where('id in (?)',ids).order("field(id,#{ids.join(",")})")
Run Code Online (Sandbox Code Playgroud)
SQL看起来像:
SELECT ... FROM ... WHERE (id in (11,5,6,7,8,9,10))
ORDER BY field(id,11,5,6,7,8,9,10)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
64897 次 |
| 最近记录: |