1

我正在查看 Rails 指南,并遇到了关于活动记录的 first_or_create 方法的部分。它指出以下代码:

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 使用时的作用,我的问题。. .

从 SQL 语句的角度来看。为什么只有在 SELECT 语句失败时才运行 Insert 语句?

4

1 回答 1

2

这就是方法的重点。first_or_create将获取第一条记录,如果没有与查询匹配的记录,则创建一条记录。您可以从源代码中看到:

# File activerecord/lib/active_record/relation.rb, line 117
def first_or_create(attributes = nil, options = {}, &block)
  first || create(attributes, options, &block)
end

SELECT语句查找所有符合该WHERE子句的记录,并且仅限于 1 条记录,因此first.

如果第一个记录不存在,则创建它,因此是INSERT语句和_or_create方法名称的一部分。


对于 SQL 语句本身,简单地调用它确实每次都会创建一条新记录。我认为相反,文档显示了所有可以生成的 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
于 2013-03-03T17:52:42.557 回答