等价于 create_with 的 Mongoid
Mongoid equivalent of create_with
是否有等效的 Active Records Model.create_with
来传递与 Mongoid 中的查找参数分开的创建参数?
# Find the first user named "Scarlett" or create a new one with
# a particular last name.
User.create_with(last_name: 'Johansson').find_or_create_by(first_name: 'Scarlett')
# => #<User id: 2, first_name: "Scarlett", last_name: "Johansson">
我发现自己使用了一个笨拙的解决方法:
user = User.find_or_initialze_by(first_name: 'Scarlett')
user.update(last_name: 'Johansson') if user.new_record?
Mongoid 的 find_or_create_by
takes an optional block which is only used when it needs to create something. The documentation isn't exactly explicit about this behavior but if you check the code you'll see that find_or_create_by
ends up as a call to this find_or
方法:
def find_or(method, attrs = {}, &block)
where(attrs).first || send(method, attrs, &block)
end
其中 method
为 :create
,如果您要查找的文档被 where
找到,则不使用 block
。
这意味着你可以说:
user = User.find_or_create_by(first_name: 'Scarlett') do |user|
user.last_name = 'Johansson'
end
获得您想要的效果。
大概这种 "the create
half uses the block" 行为应该是显而易见的,因为 create
需要一个块来初始化对象,但 find
不会。
如果您对这种未记录的行为感到疑惑,您可以在您的规范中包含对它的检查,这样您至少会知道升级何时会破坏它。
是否有等效的 Active Records Model.create_with
来传递与 Mongoid 中的查找参数分开的创建参数?
# Find the first user named "Scarlett" or create a new one with
# a particular last name.
User.create_with(last_name: 'Johansson').find_or_create_by(first_name: 'Scarlett')
# => #<User id: 2, first_name: "Scarlett", last_name: "Johansson">
我发现自己使用了一个笨拙的解决方法:
user = User.find_or_initialze_by(first_name: 'Scarlett')
user.update(last_name: 'Johansson') if user.new_record?
Mongoid 的 find_or_create_by
takes an optional block which is only used when it needs to create something. The documentation isn't exactly explicit about this behavior but if you check the code you'll see that find_or_create_by
ends up as a call to this find_or
方法:
def find_or(method, attrs = {}, &block)
where(attrs).first || send(method, attrs, &block)
end
其中 method
为 :create
,如果您要查找的文档被 where
找到,则不使用 block
。
这意味着你可以说:
user = User.find_or_create_by(first_name: 'Scarlett') do |user|
user.last_name = 'Johansson'
end
获得您想要的效果。
大概这种 "the create
half uses the block" 行为应该是显而易见的,因为 create
需要一个块来初始化对象,但 find
不会。
如果您对这种未记录的行为感到疑惑,您可以在您的规范中包含对它的检查,这样您至少会知道升级何时会破坏它。