Rails first_or_create ActiveRecord方法

时间:2014-04-15 08:51:37

标签: ruby-on-rails ruby activerecord rails-activerecord

first_or_create / first_or_create!方法在Rails中做了什么?

根据documentation,方法" 没有说明" ...

4 个答案:

答案 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_byfriends,这显然是为了替换 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)中有更多相关信息。