1

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

4

4 回答 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 回答