1

私は Rails ガイドを見ていて、アクティブなレコードの first_or_create method に関するセクションに出くわしました。それは次のコードを述べました:

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

私の質問 . . .

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 に答える