如何使用datamapper忽略重复插入

时间:2010-02-25 12:59:50

标签: ruby-on-rails ruby datamapper

我有一个datamapper模型,它在名为name的属性上有唯一索引。我想在名称尚不存在时创建新记录,并静默忽略尝试创建具有重复名称的记录。在datamapper中执行此操作的“正确”方法是什么?

4 个答案:

答案 0 :(得分: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具有相同的名称。

答案 1 :(得分: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)

答案 2 :(得分:0)

我提出的一个解决方案就是忽略异常:

  begin
    Committer.create!(:name => committer)
  rescue DataObjects::IntegrityError => e # ignore duplicate inserts
  end

如果您有更好(更惯用)的方式,请告诉我。

答案 3 :(得分: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