1

I'm following "Agile web development with rails" book. I have a problem. this is my new method in order controller:

def new
  @cart = current_cart
  if @cart.line_items.empty?
    redirect_to store_url, notice: "Your cart is empty"
    return
  end

  @order = Order.new

  respond_to do |format|
    format.html # new.html.erb
    format.json { render json: @order }
  end
end

And this is the test:

test "should get new" do
  cart = Cart.create
  session[:cart_id] = cart.id
  li = LineItem.create(product: products(:ruby))
  li.cart = cart

  get :new
  assert_response :success
end

the rake test shows a failure:

Expected response to be a <:success>, but was <302>

I checked it with rails command line as follows:

cart = Cart.create
=> #<Cart id: 24, created_at: "2012-07-09 08:39:36", updated_at: "2012-07-09 08:39:36">

products = Product.create(:title => "Lorem Ipsum", :description => "Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem", :price => 49.50, :image_url => "ruby.png")
=> #<Product id: nil, title: "Lorem Ipsum", description: "Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem", image_url: "ruby.png", price: #<BigDecimal:434f108,'0.495E2',18(45)>, created_at: nil, updated_at: nil>

li = LineItem.create(product: products)
=> #<LineItem id: 106, product_id: nil, cart_id: nil, created_at: "2012-07-09 08:41:29", updated_at: "2012-07-09 08:41:29", quantity: 1, price: nil, order_id: nil>

li.cart = cart
=> #<Cart id: 24, created_at: "2012-07-09 08:39:36", updated_at: "2012-07-09 08:39:36">

li.cart shows the corresponding cart, but cart.line_items is empty. the two model (carts and line_items) and related to each other. why is the cart.line_items empty?

ArashM
  • 1,379
  • 13
  • 18
  • Does it work if you do ` li = LineItem.create(product: products(:ruby), cart: cart)` instead? I'm thinking you set the cart for the line item, but the line item isn't saved with that new information (since it gets saved on the `create` call, and nowhere after that). – Nils Landt Jul 09 '12 at 09:17
  • It raises a MassAssignment error that way. and you're right about not saving it. – ArashM Jul 09 '12 at 09:44

2 Answers2

2

save your list item after assigning it the cart.

test "should get new" do
  cart = Cart.create
  session[:cart_id] = cart.id
  li = LineItem.create(product: products(:ruby))
  li.cart = cart

  li.save! // Do this and make sure it doesn't raise an exception.

  get :new
  assert_response :success
end

Just assigning will not register the change in the database and hence @cart.line_items will remain empty. Thus, in your controller the if check will redirect. 302 code is for redirection.

Chirantan
  • 15,304
  • 8
  • 49
  • 75
0

or just use write_attribute or update_attribute

li.write_attribute :cart, cart
Maysam Torabi
  • 3,672
  • 2
  • 28
  • 31