2013-01-18 56 views
0

我不確定這是否是範圍問題或其他問題,但我在更新測試中的對象時遇到問題:單元。Rails - 更新的對象沒有保存?

有趣的是,所有的功能在開發模式下完美地工作,但只要我切換到耙測試:單元,這一切休息。

下面是相關代碼:

class Cart < ActiveRecord::Base 

    def add_product(product) 
    current_item = line_items.find_by_product_id(product.id) 
    if current_item 
     Rails::logger.debug "Incrementing quantity" 
     Rails::logger.debug current_item.quantity 
     current_item.quantity += 1 
     Rails::logger.debug current_item.quantity 
    else 
     current_item = line_items.build(product_id: product.id, 
            price: product.price) 
    end 
    Rails::logger.debug "Added Product" 
    Rails::logger.debug current_item.quantity 
    current_item 
    end 

和相關測試

test "create new cart with one item added twice" do 
    cart = Cart.new 
    cart.add_product(products(:one)).save! 
    assert_equal 1, cart.line_items.size 
    assert_equal 36.00, cart.total_price 
    Rails::logger.debug cart.line_items.to_a 
    cart.add_product(products(:one)).save! 
    Rails::logger.debug "Added second item" 
    Rails::logger.debug cart.line_items.to_a 
    Rails::logger.debug cart.total_price 
    assert_equal 1, cart.line_items.size 
    assert_equal 72.00, cart.total_price 
    end 

和這裏的日誌輸出:

Incrementing quantity 
1 
2 
Added Product 
2 
    (0.1ms) SAVEPOINT active_record_1 
    (0.3ms) UPDATE "line_items" SET "quantity" = 2, "updated_at" = '2013-01-18 15:27:06.958210' WHERE "line_items"."id" = 980190963 
    (0.1ms) RELEASE SAVEPOINT active_record_1 
Added second item 
[#<LineItem id: 980190963, product_id: 1, cart_id: nil, created_at: "2013-01-18 15:27:06", updated_at: "2013-01-18 15:27:06", quantity: 1, price: 36>] 
36 

EW量(已根據上次更改日誌)。有趣的是,在函數本身中,數量字段正在更新爲兩個。它甚至保存到SQL數據庫。但是,當我調用cart.line_items時,它甚至有更新的字段,但它不保存新的數量(根據最後一個日誌已經更改)。

回答

3

Rails不具有默認的標識映射。這意味着,只要你做一個LineItem.find(1)和另一LineItem.find(1)你會得到從同一行中的數據庫中的數據的創建,但沒有它們之間的任何連接兩個不同的對象。如果其中一個被更改並保存到數據庫中,另一個對象不會知道它並仍然有舊數據。

在你的榜樣,你正在做的line_items.find_by_product_id(product.id)這將做一個查找和每次都返回一個新的對象。與先前加載到cart.line_items的任何LineItem對象沒有關係。

有兩種選擇,更新陳舊的對象的數據。其中之一是.reload方法,該方法將從數據庫中重新加載一個對象的所有數據。另一種選擇是將true傳遞給cart.line_items關聯。類似於cart.line_items(true)的調用將強制對數據庫的新查詢獲取所有行項目。

,此錯誤只打你的測試過程中,原因很簡單:在發展模式,插入和閱讀,通常在兩個單獨的請求完成,因此所有的對象都是新鮮從數據庫每次加載。

+0

感謝您的解釋。但是,重新加載不適合我。 'cart.line_items.reload'清空購物車,(它現在有0個對象),如同'cart.lines_items(true)'。有關如何正確重新載入的任何建議?另外,如何選擇相同的對象,而不是使用.find()並生成一個新對象? – Xiv

+0

更新:只需要做一個cart.list_items.each {| item | item.reload} m逐個重新加載對象。 – Xiv