2009-11-05 68 views
13

也許一些ruby專家可以在調用save()時瞭解activerecord如何知道如何插入或更新。它背後的邏輯是什麼?它會檢查主鍵是否空白或者是否有插入,如果不是更新?activerecord如何知道執行插入或更新?

+0

優秀的問題。 – 2012-10-13 13:28:58

回答

23

雖然它的罰款,對某些人說「RTFM」我寧可多走通,但是,仍然entirely-沒用的,當-Rails的3-來自-不折不扣的變化,一切響應:

它是如何工作的Rails的2.3(又名 「今天」)

save電話create_or_update它看起來像這樣:

def create_or_update 
    raise ReadOnlyRecord if readonly? 
    result = new_record? ? create : update 
    result != false 
end 

可以忽略此方法的第一行,因爲它只有在記錄是隻讀的,會產生錯誤(這通常不是,但在加入的情況下它可能是) 。我們感興趣的是方法中的第二和第三行。

第二行調用new_record?它被定義爲這樣的:

# Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet; otherwise, returns false. 
    def new_record? 
    @new_record || false 
    end 

和變量@new_recordinitialize設置(new電話initialize,給了我們一個新的對象,一些背景紅寶石福在這裏)方法被調用。

因此,如果這是@new_recordtrue會打電話create,如果它是假的,它會調用update這給我們帶來了你以後,我想。

此外,當您找到一條記錄時,它不會呼叫initialize,因此不會設置@new_record。如果您注意到,new_record?後面的代碼是@new_record || false,這意味着如果未設置@new_record,它將返回false。

比方說,例如你想找到最後的Forum記錄,所以你會做Forum.last

  1. 此呼籲Forum類,它的ActiveRecord ::繼承基礎
  2. lastcallsfind類方法的last方法。
  3. findcallsfind_last
  4. find_lastcallsfind_initial
  5. find_initialcallsfind_every
  6. find_everycallsfind_by_sql
  7. find_by_sql電話instantiate

你會在這裏看到,這個變化無處是@new_record集合,因此find獲得的任何記錄都不會是新記錄。

希望這可以幫助你理解。

+0

非常好的答案,我認爲你的時間來爲你寫它。我也有興趣知道什麼會將@nw_record設置爲false?如果它從數據庫中提取記錄,會執行查找操作嗎? – rip747 2009-11-06 15:52:58

+0

我已經使用find方法更新了帖子。 – 2009-11-07 00:20:46

+0

是否有自己修改「new_record」屬性 – 2013-09-23 01:10:40

1

查看activerecord的文檔here和源代碼there

+0

我一直在閱讀文檔和代碼,無法圍繞它進行包裝。 – rip747 2009-11-05 21:54:17

+0

你也連接到主。他可能使用2.3。 – 2009-11-06 03:33:03

2

它原則上依賴於new_record?方法。
如果是新記錄,則此方法返回true,如果不是,則返回false。

其實這並不難。

  • 當你得到一個現有的記錄,這不是新的。所以new_record?可以直接返回false。
  • 當您創建新記錄(Model.new)時,new_record?將返回true。這是一個新紀錄。
  • 當您保存新記錄時,它不再是新的。內部變量@new_record得到更新。 new_record?將不會返回true。

要看到當它發生時,去ActiveRecord::Base,線路2911

self.id ||= new_id 

    @new_record = false 
    id 
    end 
+0

當他可能使用2.3時,你會鏈接到主人。 – 2009-11-06 03:32:25

+0

這並不改變我的論點。但我已經更新了鏈接。 – 2009-11-06 08:04:13

相關問題