first_or_create
/ first_or_create!
方法在Rails中做了什么?
根据documentation,方法" 没有说明" ...
答案 0 :(得分:50)
来自Guides
<强> first_or_create 强>
first_or_create
方法检查是否首先返回nil。如果确实返回nil,则调用create。当与where方法结合使用时,这非常强大。我们来看一个例子。
假设您要查找名为“Andy”的客户端,如果没有,请创建一个并另外将其locked属性设置为false。你可以通过运行:
来实现Client.where(:first_name => 'Andy').first_or_create(:locked => false)
# => #<Client id: 1, first_name: "Andy", orders_count: 0, locked: false, created_at: "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27">
此方法生成的SQL如下所示:
SELECT * FROM clients WHERE (clients.first_name = 'Andy') LIMIT 1
BEGIN
INSERT INTO clients (created_at, first_name, locked, orders_count, updated_at) VALUES ('2011-08-30 05:22:57', 'Andy', 0, NULL, '2011-08-30 05:22:57')
COMMIT
first_or_create
返回已存在的记录或新记录。在我们的例子中,我们还没有一个名为Andy的客户端,因此创建并返回了记录。
<强> first_or_create!强>
如果新记录无效,您还可以使用first_or_create!
引发异常。本指南不涉及验证,但我们暂时假设您暂时添加
validates :orders_count, :presence => true
到您的客户端模型。如果您尝试在不传递orders_count的情况下创建新客户端,则该记录将无效并将引发异常:
Client.where(:first_name => 'Andy').first_or_create!(:locked => false)
# => ActiveRecord::RecordInvalid: Validation failed: Orders count can't be blank
答案 1 :(得分:0)
获取与您指定的内容匹配的第一条记录,如果没有匹配则创建一条
答案 2 :(得分:0)
如果您检查来源,您会发现它们几乎相同。唯一的区别是第一个叫做&#34;创建&#34;方法和另一个&#34;创建!&#34;。这意味着如果创建不成功,第二个将引发异常。
答案 3 :(得分:0)
我认为现在通常应该避免使用 first_or_create
。 (虽然它仍然在 Rails 6.1.1 中。)在 4.0 中,他们添加了 find_or_create_by
和 friends,这显然是为了替换 first_or_create
方法。 first_or_create
曾经在 guides 中提及,现在是 not。并且不再记录 in the code(从 Rails 4.0 开始)。它是在 Rails 3.2.19 中引入的。
原因是:
看起来 first_or_create(attrs)
是 first(attrs) || create(attrs)
,实际上它是 first || create(attrs)
。正确的用法是:
Model.where(search_attrs).first_or_create(create_attrs)
也就是说,它可能会混淆人们。 first(attrs) || create(attrs)
就是 find_or_create_by
所做的。
此外,使用 first_or_create
会引入一个范围,这可能会以意想不到的方式影响 create
回调。
在 changelog(搜索 first_or_create
)中有更多相关信息。