2013-02-12 69 views
1

我在爲活動記錄關聯進行佈線時經常遇到問題,我期待着最終了解是什麼導致了它(而不僅僅是解決它)。爲什麼我需要重新加載這個兒童關聯?

當通過parent.children < <將孩子與父母關聯時,對孩子的引用正確地更新自己。如果關係建立反向(如果通過child.parent =完成),則這不起作用。

爲什麼會發生這種情況?有沒有辦法使雙方的關係?我試過inverse_of以前沒有成功。我希望是因爲我對這裏發生的事情不夠了解。

例子:

鑑於這些模型:

class Task < ActiveRecord::Base 
    belongs_to :batch 

    attr_accessor :state 
end 

class Batch < ActiveRecord::Base 
    has_many :tasks 

    def change_tasks 
    tasks.each { |x| x.state = "started" } 
    end 
end 

爲什麼第一規格失敗,但第二遍?我可以進行第一次傳球嗎?出於某種原因,我需要重新加載第一個規格,但不是在第二個規格。

describe "avoiding reload" do 

    context "when association established via child.parent=" do 
    it "updates child references" do 
     b = Batch.create 
     t = Task.create(batch: b) 

     b.change_tasks 

     b.tasks[0].state.should == "started" # passes 
     t.state.should == "started" # fails!? 
     t.reload.state.should == "started" # passes, note the reload 
    end 
    end 

    context "when association established via parent.children<<" do 
    it "updates child references" do 
     b = Batch.create 
     t = Task.create 
     b.tasks << t 

     b.change_tasks 

     b.tasks[0].state.should == "started" # passes 
     t.state.should == "started" # passes 
    end 
    end 

end 

感謝您的幫助。

回答

1

簡短的答案是對象是在第一個規格和第二個不同。

在第一個規範,你有2個不同的對象(嘗試在軌控制檯檢查):

t.object_id != b.tasks[0].object_id 

雖然這兩個對象是指相同的記錄,它們是不同的。您已更改b.tasks[0],但t保持不變直到重新加載。

在第二規格只有對象:

t.object_id == b.tasks[0].object_id 

所以t任何更新將在b.tasks[0]反映,並反之亦然。

1

它與您的操作順序有關。

在第一次測試中,您可以撥打Task.createcreate取參數並保存到數據庫並返回保存後的結果。它對批次的引用不一定是您在測試範圍內處理的同一批次。

在第二個測試中,您在調用create之後分配任務。然後立即訪問它。所以相同的任務t是在change_taskst.state.should == "started"期間的引用。

相關問題