我想知道在短时间内验证记录是否可能有活跃的记录暂缓?例如,在我的webapp中,我有一个名为Sizes
的表,其中包含一个名为sort_order
的属性,用户可以通过修改sort_order
来重新组织显示大小的顺序。当他们这样做时,我有这个函数,它将遍历大小列表并重新计算排序顺序,相应地更新列。
def update_size_order
@size_ids = params[:categories]
n = 0
ActiveRecord::Base.transaction do
@size_ids.each do |temp|
temp = temp.split('_')
id = temp[1]
size = Size.find(id)
size.sort_order = n
n += 1
size.save!
end
end
render :json => {}
end
问题出现了,因为在我的模型中我有
validates :sort_order, presence: true, uniqueness: true
但是当模型试图保存size
时,我收到错误,因为尺寸不一定是唯一的。有没有办法让ActiveRecord在此函数完成之前不执行验证?我的谷歌搜索技能似乎已经达到了他们的匹配,但我觉得这个问题有一个简单的解决方法。谢谢你的帮助!
答案 0 :(得分:1)
使用size.update_attribute :sort_order, n
代替save!
。它只是更新数据库而不运行任何形式的验证。由于您在事务中运行它,您应该没问题,但通常您应该避免使用update_attribute
,因为它绕过了验证和回调。
此外,each_with_index
是您的朋友:
def update_size_order
@size_ids = params[:categories]
ActiveRecord::Base.transaction do
@size_ids.each_with_index do |temp,n|
temp = temp.split('_')
id = temp[1]
Size.find(id).update_attribute :sort_order, n
end
end
render :json => {}
end
由于您只对更新属性感兴趣,因此您也可以跳过实例化AR对象的整个过程,并放弃Size.find(id)
调用,转而使用update_all
。这将默默地忽略任何未找到的ID,但是当您减半正在运行的查询数时,它将显着提高循环的性能。而不是select
查询,然后完全实例化AR模型,并为每条记录update
,它将只生成update
查询:
@size_ids.each_with_index do |temp,n|
temp = temp.split('_')
id = temp[1]
Size.where(id: tmp[1]).update_all(sort_order: n)
end
答案 1 :(得分:1)
让我们说出这个:
validates: :sort_order,
presence: true,
uniqueness: true,
on: :create
这就是你想要的吗? 这样,您的验证仅在创建新对象时执行。