2013-08-23 25 views
2

我有下面的代碼,它工作正常,沒有錯誤,但絕不模型得到保存...回報率:first_or_initialize塊不保存

myarray.each do |item| 

    r = MyModel.unscoped.where(:site_id => @site.id, :url => item['permalink_url']).first_or_initialize do |r| 
     r.title    = 'asdasdadaddjfgnfd' 
     r.save! 
    end 
end 

終端顯示SQL SELECT語句試圖找到時模型,但UPDATE/INSERT語句從不運行。

我在這裏錯過了什麼?

回答

3

您正在尋找first_or_createfirst_or_initialize只是初始化對象(可能需要保存,但不一定)。

你現有的代碼可能會工作方式如下:

r = MyModel.unscoped.where(:site_id => @site.id, :url => item['permalink_url']).first_or_initialize do |r| 
    r.title    = 'asdasdadaddjfgnfd' 
end 

r.save! 
+0

謝謝,但這樣會使用1更多的SQL查詢比必要的,'first_or_initialize'更適合我的目的 – Ashley

6

Rails的first_or_*方法只調用了initializecreate一部分傳遞塊。如果找到記錄,方法只是返回它,所以傳遞的塊永遠不會運行。 Check the source

因此,您可以在first_or_*方法中使用塊來初始化新項目,而不是更新現有項目。很有可能存在具有這些條件的記錄,並且不會更新。

試運行更新的代碼,類似

myarray.each do |item| 

    r = MyModel.unscoped.where(:site_id => @site.id, :url => item['permalink_url']).first_or_initialize 
    r.title    = 'asdasdadaddjfgnfd' 
    r.save! 

end 
+0

謝謝,我結束了'.tap()'所以我可以使用我的存在克塊結構,但這也是一個有效的答案 – Ashley

6

我解決了這個利用:

.first_or_initialize.tap() do |r|

但下面的評論也與此有關

+0

正是我正在尋找我的種子! – laffuste

+0

@laffuste你不需要使用tap()。 'find_or_initialize'已經返回對象。 – Mohamad