我正在尝试复制一个记录及其所有后续嵌套的子关联。以下是问题的简化。
我有以下Foo
型号:
class Foo < ActiveRecord::Base
belongs_to :project,
inverse_of::foos
validates :name,presence:true,uniqueness:{ scope: :project_id },
format:{ with: /[0-9a-zA-Z\s\/_:\-.|]*/ }
end
我正在复制project
这样:
origin = Project.first
clone = origin.dup
clone.foos << clone_records(origin.foos)
clone.save
def clone_records(records)
clones = []
records.each do |record|
cloned_record = record.dup
cloned_record.project_id = nil
cloned_record.name = "Copy of " + record.name
# Which Generates:
#<Foo:0x007f94353fc200> {
# :id => nil,
# :name => "Copy of Some Foo",
# :project_id => nil
#
# }
clones.push(cloned_record)
end
return clones
end
问题是,当我复制project
并分配新生成的,重命名的foos
时,保存后我会收到错误:
Foo Exists (0.4ms) SELECT 1 AS one FROM "foos" WHERE ("foos"."name" = 'Copy of Some Foo' AND "foos"."project_id" = 1) LIMIT 1
但是,不存在具有该名称的foo
:
Foo.where(name: "Copy of Some Foo")
# Foo Load (0.6ms) SELECT "foos".* FROM "foos" WHERE "foos"."name" = $1 ORDER BY "foos"."id" ASC [["name", "Copy of Some Foo"]]
# []
谁能告诉我这里会发生什么?我认为它与验证有关,但我不明白为什么:1)它认为这个新记录存在,2)为什么新记录在我的原始项目中设置了project_id
已明确废除该字段。
答案 0 :(得分:0)
问题是uniqueness: { scope: :project_id }
也适用于nil
值。因此,如果您有两条记录,并且它们都project_id == nil
会违反唯一性约束。
这是一种在保持唯一性约束的同时允许nil值的方法:
uniqueness: { scope: :project_id }, unless: Proc.new { |record| record.project_id.blank? }
当ActiveRecord抱怨Foo Exists
时,它会回滚提交,因此克隆的Foos不会持久存储到数据库中。
答案 1 :(得分:0)
首先,这一行:
$.getJSON(uri,
function (data) {
carparksArray = [];
$('#here_data').empty(); // Clear existing text.
// Loop through the list of carparks.
$.each(data, function (key, val) {
carparksArray.push([val.Name, val.Latitude, val.Longitude]);
});
console.log(carparksArray);
loadScript();
});
根本不是错误,只是指示Rails运行您的唯一性验证的日志。和,
2)当我明确废除该字段时,为什么新记录将project_id设置为origin项目。
你确定吗?它的project_id确实设置为原始项目?在我看来,project_id只是设置为新创建的项目的id。