在ActiveRecord关联中重新排序唯一有序模型

时间:2013-04-24 22:45:30

标签: validation activerecord model-associations

我有包含许多项目的List模型。这些项目的priority在列表范围内是唯一的。

class List < ActiveRecord::Base
  has_many :items
  accepts_nested_attributes_for :items
end

class Item < ActiveRecord::Base
  validates :priority, uniqueness: { :scope => :list_id }
end

因此,如果我从API调用返回给定列表,它看起来像这样:

{
  items: [
    { "id": 1, "priority": 1 },
    { "id": 2, "priority": 2 },
    { "id": 3, "priority": 3 }
  ]
}

用户重新排列前端的项目,并向服务器发出PUT请求

{
  items_attributes: [
    { "id": 1, "priority": 3 },
    { "id": 2, "priority": 1 },
    { "id": 3, "priority": 2 }
  ]
}

但这会失败。当其中一个尝试保存时,它将检查是否存在具有相同列表ID和优先级的另一个项目。由于数据库中尚未更新其他项目,因此此验证将失败。

如何实现此更新?

1 个答案:

答案 0 :(得分:0)

在list_id列中允许nils,以便重置值。

validates :priority, uniqueness: { :scope => :list_id }, unless: Proc.new { |l| l.list_id.blank? }

在您的控制器中,重置列:

ItemController.update_all("priority = null");

然后像现在一样使用传递的参数设置它们。只需确保在保存(valid?)之前测试模型的有效性。