种子文件 - 将id列添加到现有数据

时间:2015-04-20 15:48:09

标签: ruby-on-rails ruby-on-rails-4

我的种子文件在国家/地区表格中填入了国家/地区列表。但现在需要将其更改为对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列已经存在于数据库中了吗?

7 个答案:

答案 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代替codeid。这样你就不会有尝试创建重复的国家代码的问题。

Country.find_or_initialize_by(code: value[:code])

我认为您的ID可能会遇到问题,但您必须对此进行测试。做你正在做的事情通常是不好的做法。他们是否改变或现在应该是无关紧要的。您的种子文件应该引用正在创建的对象而不是ID。

另外请确保您没有使用任何default_scopes ...这会影响find_or_initialize_by的工作方式。