2011-09-25 76 views
0

我有2個模型。 A UserTask。下面是他們兩個代碼:Rails testing has_many association failure

class User < ActiveRecord::Base 
    has_many :tasks 
    has_many :assigned_tasks, :class_name => 'Task', :foreign_key => 'assigned_user_id' 
end 

class Task < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :assigned_user, :class_name => 'User', :foreign_key => 'assigned_user_id' 
end 

的模式是比較明顯的,但爲了保持一致性,這是它的外觀:

ActiveRecord::Schema.define(:version => 20110925050945) do 
    create_table "tasks", :force => true do |t| 
    t.string "name" 
    t.integer "user_id" 
    t.integer "assigned_user_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "users", :force => true do |t| 
    t.string "name" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 
end 

我添加了一個測試案件爲assigned_tasks關係。它看起來像這樣:

class UserTest < ActiveSupport::TestCase 
    test "assigned tasks" do 
    u1 = User.create(:name => 'john') 
    u2 = User.create(:name => 'dave') 

    assert_empty u2.assigned_tasks # LOOK AT ME 

    task = u1.tasks.create(:name => 'some task', :assigned_user_id => u2.id) 

    assert_equal 1, u2.assigned_tasks.size 
    end 
end 

現在,這個測試案例失敗。它最後的斷言失敗了。如果我刪除以前的斷言(標記爲「看我」),這個測試通過很好。如果我將此行更改爲assert u2.assigned_tasks,它也會通過正常。意思是在empty?被稱爲u2.assigned_tasks時,並且只有在empty?被調用時纔會中斷。在斷言通過的地方,下一個失敗。這裏的失敗:

UserTest: 
    FAIL assigned tasks (0.12s) 
      <1> expected but was 
<0>. 
      test/unit/user_test.rb:12:in `block in <class:UserTest>' 

所以,出現一次empty?被稱爲原始u2.assigned_tasks陣列,任務沒有實際添加/關聯與它的分配的用戶。然而,這似乎在控制檯中工作正常。

道歉,如果我完全忽略了一些簡單的東西,但我真的無法理解這一點。任何正確的方向點都會非常有幫助。由於

PS:3.1的Rails與香草應用

回答

2

您需要重新加載assigned_tasks,或u2

# This line causes assigned_tasks to be loaded and cached on u2. Not the calling 
# of empty?, but rather the loading of the association. 
assert_empty u2.assigned_tasks 

# but then you actually make the task here 
task = u1.tasks.create(:name => 'some task', :assigned_user_id => u2.id) 

# so when this assertion happens, u2 already has an empty set of tasks cached, 
# and fails 
assert_equal 1, u2.assigned_tasks.size 

# however either of these should pass 
assert_equal 1, u2.assigned_tasks(true).size 
assert_equal 1, u2.reload.assigned_tasks.size 

inverse_of選項有助於改善在內存中的關聯行爲,同時也可以解決你的問題(無需重新加載)。閱讀關於here。它會看起來像這樣(但我不積極,它會在這種情況下工作):

# on User 
has_many :assigned_tasks, ..., :inverse_of => :assigned_user 

# on Task 
belongs_to :assigned_user, ..., :inverse_of => :assigned_tasks 

# in your test you might have to change the task creation to: 
u1.tasks.create(:name => 'some task', :assigned_user => u2) 
+0

哦快照,事實證明我**是**只是俯瞰簡單的東西。非常感謝,我已經知道這一點,在這裏完全忽略它。此外,您的鏈接指向一個YouTube視頻 –

+0

哈!你的意思是你沒有在關於Faxanadu音樂的視頻中找到任何有關軌道協會的良好信息?糟糕:-P – numbers1311407

+1

我不會說謊,在意識到你要麼輸入/粘貼,要麼我被拖了之前,我至少還有一分鐘的時間。這真是令人尷尬! :d –