如何忽略使用数据映射器的重复插入
问题描述:
我有一个datamapper模型,它在名为property的属性上具有唯一索引。我想在名称尚不存在时创建新记录,并默默地忽略尝试创建具有重复名称的记录。在datamapper中做这件事的“正确”方法是什么?我想出了如何忽略使用数据映射器的重复插入
答
我认为最好的答案是first_or_create使用,这成丹上面所指出的,已建成的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)
答
一种解决方案是简单地忽略异常:
begin
Committer.create!(:name => committer)
rescue DataObjects::IntegrityError => e # ignore duplicate inserts
end
如果你有这样做的更好(更地道)的方式,请让我知道。
答
最好的方法是使用DM-验证的宝石,并确保指定的name属性作为唯一的,例如:
class Committer
include DataMapper::Resource
# ... other properties ...
property :name, String, :length => 1..100, :required => true, :unique => true
end
的DM-验证创业板将反思你的模型,并自动设置验证为您的物业。在这种情况下,它不允许多个提交者具有相同的名称。
答
这里是另一个解决方案,我想出了:
require 'dm-core'
require 'dm-validations'
require 'dm-more'
record = Committer.find_or_create(:name => committer)
如果你在西纳特拉用这个,需要DM-更多的似乎会导致其他 问题。我的解决办法是要求我自己的文件,只有 包含以下代码:
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
谢谢丹。我主要关心的不是如何执行唯一性,而是如何执行INSERT IGNORE - 即如何创建新记录,但是如果重复记录已经存在,将自动失败。我想知道做这件事的最好方法是什么。 – cayblood 2010-02-26 06:09:13
不能在没有插件的情况下在DataMapper中执行INSERT IGNORE,但是没有一个可以执行此atm。 – dkubb 2010-02-26 18:57:36
只是为了澄清,我并不是故意特意要求使用INSERT IGNORE。任何完成我目标的事情都很好。 – cayblood 2010-02-27 21:11:04