2013-03-03 37 views
1

我在看Rails指南,遇到了the section on active record's first_or_create method。它說,下面的代碼:你能解釋SQLwise爲什麼這個INSERT語句只有在SELECT語句失敗時才運行? (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語句?

回答

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 
+0

感謝快速反應AJ。我明白它是如何工作的,我的問題是**爲什麼insert語句每次都不執行**?除非SELECT語句返回任何記錄,否則會阻止INSERT語句運行? – 2013-03-03 18:49:49

+0

啊sql問題 – AJcodez 2013-03-03 18:50:31

+0

的確,這是如何工作的?我編輯了更具體的問題。 – 2013-03-03 18:51:40