我有一个 datamapper 模型,它在名为 name 的属性上有一个唯一索引。我想在名称不存在时创建新记录,并默默地忽略创建具有重复名称的记录的尝试。在数据映射器中执行此操作的“正确”方法是什么?
问问题
1375 次
4 回答
1
我认为最好的答案是使用 first_or_create,正如 Dan 上面指出的那样,它已经内置在 datamapper 中,因此不需要声明。
require 'dm-core'
require 'dm-validations'
class Committer
include DataMapper::Resource
property :id, Serial
property :name, String, :unique_index => true
validates_present :name
validates_is_unique :name
end
committer = "George"
record = Committer.first_or_create(:name => committer)
于 2010-03-02T14:51:26.160 回答
1
最好的方法是使用 dm-validations gem,并确保您的 name 属性被指定为唯一的,例如:
class Committer
include DataMapper::Resource
# ... other properties ...
property :name, String, :length => 1..100, :required => true, :unique => true
end
dm-validations gem 将自省您的模型并自动为您的属性设置验证。在这种情况下,它不允许多个 Committer 具有相同的名称。
于 2010-02-25T19:55:29.060 回答
0
我想出的一种解决方案就是忽略异常:
begin
Committer.create!(:name => committer)
rescue DataObjects::IntegrityError => e # ignore duplicate inserts
end
如果您有更好(更惯用)的方法,请告诉我。
于 2010-02-25T13:32:40.403 回答
0
这是我想出的另一个解决方案:
require 'dm-core'
require 'dm-validations'
require 'dm-more'
record = Committer.find_or_create(:name => committer)
如果您在 sinatra 中使用它,则需要 dm-more 似乎会导致其他问题。我的解决方案是要求我自己的文件只包含以下代码:
module DataMapper
module Model
def first_or_create(conditions = {}, attributes = {})
first(conditions) || create(conditions.merge(attributes))
end
alias find_or_create first_or_create
end
end
于 2010-02-26T06:12:29.583 回答