我有一个ActiveRecord模型数组,我想重编号一个列并批量更新它们。代码如下:
rules = subject.email_rules.order(:number)
rules.each_with_index do |rule, index|
rule.number = index + 1
end
EmailRule.update(rules.map(&:id), rules.map { |r| { number: r.number } })但是这会创建N个SQL语句,我想要1,有什么方法可以做到吗?
发布于 2017-08-07 13:46:41
假设您正在使用postgres,您可以使用row_number和看起来有点奇怪的更新/从结构。这是基本版本:
UPDATE email_rules target
SET number = src.idx
FROM (
SELECT
email_rules.id,
row_number() OVER () as idx
FROM email_rules
) src
WHERE src.id = target.id您可能需要在subject上对此进行详细分析,当然还需要包含按数字排序的顺序,如下所示:
UPDATE email_rules target
SET number = src.idx
FROM (
SELECT
email_rules.id,
row_number() OVER (partition by subject_id) as idx
FROM email_rules
ORDER BY number ASC
) src
WHERE src.id = target.id(假设subject_id是关联主题/email_rules的外键)
发布于 2017-08-07 13:25:28
您可以选择的一种方法是将所有交互都放在一个事务中,它至少会在事务结束时进行一次提交,从而使其速度更快。
ActiveRecord::Base.transaction do
...
endhttps://stackoverflow.com/questions/45547580
复制相似问题