::first_or_create
(自 v3.2.1 起可用)按照包装盒上的说明进行操作。
Model.where(find: 'find_value').
first_or_create(create: 'create_value')
# If a record with {find: 'find_value'} already exists:
before #=> #<Model id: 1, find: "find_value", create: nil>
after #=> #<Model id: 1, find: "find_value", create: nil>
# Otherwise:
before #=> nil
after #=> #<Model id: 2, find: "find_value", create: "create_value">
如果您还希望它更新已经存在的记录,请尝试:
Model.where(find: 'find_value').
first_or_create(create: 'create_value').
update(update: 'update_value')
# If one already exists:
before #=> #<Model id: 1, find: "find_value", create: nil, update: nil>
after #=> #<Model id: 1, find: "find_value", create: nil, update: "update_value">
# If it already matches, no UPDATE statement will be run:
before #=> #<Model id: 1, find: "find_value", create: nil, update: "update_value">
after #=> #<Model id: 1, find: "find_value", create: nil, update: "update_value">
# Otherwise:
before #=> nil
after #=> #<Model id: 2, find: "find_value", create: 'create_value', update: "update_value">
编辑 2016-03-08:根据Doug的评论,如果您的验证在#create
and#update
调用之间失败,或者您想最小化数据库调用,您可以::first_or_initialize
改用,以避免在第一次调用时保留记录。但是,您必须确保您致电#save
或#update
之后才能保留记录(我不确定是否#update
适用于尚未保留的记录):
Model.validates :update, presence: true # The create call would fail this
Model.where(find: 'find_value').
first_or_initialize(create: 'create_value'). # doesn't call validations
update(update: 'update_value')
(注意。有一种方法称为#create_or_update
,但不要被您在 Google 上找到的任何文档所迷惑;这只是#save
.