0

我正在使用 rake 任务用一些初始数据填充我的数据库。我想在表中创建一堆条目,其中包含前几个 ID,因此它们始终存在,并且始终具有这些 ID。我不介意在开发环境中是否有人添加/删除/修改记录,但我总是希望前 5 个 id 具有值。这是我的 lib/tasks/bootstrap.rb 文件的简化版本:

namespace :bootstrap do
    desc "Create the default problem types"
    task :default_problem_types => :environment do
        ProblemType.create( :id => 1, :name => 'Wrong location', :description => 'blah' )
        ProblemType.create( :id => 2, :name =>  'Wrong name', :description => 'blah' )
        ProblemType.create( :id => 3, :name =>  'Wrong details', :description => 'blah' )
        ProblemType.create( :id => 4, :name =>  'Duplicate', :description => 'blah' )
        ProblemType.create( :id => 5, :name =>  'No longer exists', :description => 'blah' )
    end

    desc "Run all bootstrapping tasks"
    task :all => [:default_problem_types]
end

这适用于空数据库。它在 problem_types 表中创建了 5 个新条目:

1 - Wrong Location 
2 - Wrong name 
3 - Wrong details 
4 - Duplicate 
5 - No longer exists

问题是,如果我再次运行它,它会创建 5 条新记录,ID 为 6、7、8、9、10。尽管我为已经存在的 create() 调用提供了 ID。我希望这些调用会失败,因为如果我尝试执行以下 SQL:

insert into problem_types (id, name, description) values (1, 'foo', 'bar');

... 它失败:

错误 1062 (23000):键 'PRIMARY' 的重复条目 '1'

如果 ID 已经存在,如何让 create() 方法失败?

谢谢。

4

2 回答 2

0

经验法则:您不会自己分配 ID。让数据库做它的工作。如果您希望您的问题名称是唯一的,那么您可以添加validates_uniqueness_of :name到模型文件中,如果存在相同的名称,则不会创建记录

于 2013-02-18T19:07:49.050 回答
0

使用动态find_or_create_byfind_or_initialize_by方法。您可以在 Active Record 查询接口的 Rails 指南中阅读更多相关信息。它们允许您为每个编写类似这样的内容,ProblemType而无需按名称创建重复项:

problem_type = ProblemType.find_or_initialize_by_name('Wrong location')
problem_type.description = "blah"
problem_type.save

我同意@benchwarmer;最好避免自己管理主键。如果您必须具有某个语义值的数字标识符,请尝试添加单独的列并相应地设置该值。

于 2013-02-18T20:03:08.447 回答