我的种子文件在国家/地区表格中填入了国家/地区列表。但现在需要将其更改为对id进行硬编码(而不是为我生成id列的rails)。
我添加了id列和值,如下所示:
zmb: {id: 103,code: 'ZMB', name: Country.human_attribute_name(:zambia, default: 'Error!'), display_order: nil, create_user: user, update_user: user, eff_date: Time.now, exp_date: default_exp_date},
skn: {id: 104,code: 'SKN', name: Country.human_attribute_name(:st_kitts_and_nevis, default: 'Error!'), display_order: nil, create_user: user, update_user: user, eff_date: Time.now, exp_date: default_exp_date}
countries.each { |key, value| countries_for_later[key] = Country.find_or_initialize_by(id: value[:id]); countries_for_later[key].assign_attributes(value); countries_for_later[key].save!; }
上面只是一个片段。我为每个国家添加了一个ID:
但是当我运行db:seed
时,我收到以下错误:
ActiveRecord::RecordInvalid: Validation failed: Code has already been taken
我是rails的新手,所以我不确定导致这种情况的原因 - 是因为ID列已经存在于数据库中了吗?
答案 0 :(得分:0)
错误与代码:Code has already been taken
有关。你有一个验证,说Code应该是uniq。您可以删除所有国家/地区并再次加载种子。
答案 1 :(得分:0)
在rails控制台中运行:
Country.delete_all
然后重新运行种子:
rake db:seed
答案 2 :(得分:0)
是的,这是由于重复输入。在这种情况下,在rails控制台中运行ModelName.delete_all
,然后再次在当前项目目录中运行rake db:seed
。希望这有效。
答案 3 :(得分:0)
添加
行countries_for_later[key].id = value[:id]
问题在于您无法设置:id => value [:id]改为Country.new,因为id是一个特殊属性,并且自动受到大规模赋值的保护
所以它将是:
countries.each { |key, value|
countries_for_later[key] = Country.find_or_initialize_by(id: value[:id])
countries_for_later[key].assign_attributes(value)
countries_for_later[key].id = value[:id] if countries_for_later[key].new_record?
countries_for_later[key].save(false)
}
答案 4 :(得分:0)
ActiveRecord::RecordInvalid: Validation failed: Code has already been taken
是唯一性验证器的默认错误消息:code。
运行rake db:reset肯定会清除并重新设置数据库。虽然不确定硬编码的ID。
请检查:Overriding id on create in ActiveRecord
您必须使用
禁用保护save(false)
或
Country.create(attributes_for_country, without_protection: true)
我没有测试过这个,请小心你的验证器。
答案 5 :(得分:0)
您在种子文件中使用的ids数据:除了Rails之外有什么意义吗?例如
zmb: {id: 103,code: 'ZMB',
这是赞比亚的一些外部数据,其中103是国际公认的国家代码表中的ID吗? (在我的国家数据库中,赞比亚的“numcode”值是894)。如果是,那么你应该将它重命名为其他东西,并让Rails决定id字段应该是什么。
一般来说,在轨道中使用ID值进行捣乱对你来说是一件痛苦的事。我建议不要这样做。如果你需要对数据进行测试,那么使用其他一些独特的字段(比如“代码”)来测试是否已经设置了关联等,或者你想做什么,让Rails担心ID的值是什么。
答案 6 :(得分:0)
我的想法是你的数据库中有现有数据......让我们说
[{id:1 , code: 'ABC'},
{id:2 , code: 'DEF'}]
现在运行例如{id: 3, 'DEF'}
的种子文件。
因为您使用带有ID的find_or_initialize_by
,所以您遇到了错误。因为您可以插入重复项。
我说您应该清除您的数据,但您可以尝试使用find_or_initialize_by
代替code
来id
。这样你就不会有尝试创建重复的国家代码的问题。
Country.find_or_initialize_by(code: value[:code])
我认为您的ID可能会遇到问题,但您必须对此进行测试。做你正在做的事情通常是不好的做法。他们是否改变或现在应该是无关紧要的。您的种子文件应该引用正在创建的对象而不是ID。
另外请确保您没有使用任何default_scopes ...这会影响find_or_initialize_by
的工作方式。