I'm trying to set up a has_many_through relationship where a User can have a cart with an item. I can add carts to the user (chip.carts << chips_cart
) but I can't push items into my carts (chips_cart << coffee
).
I get NoMethodError: undefined method
<<' for #<Cart id: 5, user_id: nil>`
class User < ActiveRecord::Base
has_many :carts
has_many :items, through: :carts
end
class Cart < ActiveRecord::Base
belongs_to :user
has_many :items
end
class Item < ActiveRecord::Base
belongs_to :carts
has_many :users, through: :carts
end
chip = User.create(username: "Chip")
chips_cart = Cart.create
socks = Item.create(item: "socks", price: 5.00)
As pointed out by Hubert you have a pluralization error:
belongs_to :cart # not :carts
The name of belongs_to/has_one
assocations should always be singular.
And you don't need to use the shovel operator <<
in the first place:
chip = User.create(username: "Chip")
chips_cart = chip.carts.create
socks = chips_cart.items.create(item: "socks", price: 5.00)
Individual records don't respond to <<
. Which is why you are getting NoMethodError: undefined method <<' for #<Cart id: 5, user_id: nil>
. If you want to use the shovel operator you need to do chips_cart.items << socks
instead of chips_cart << socks
.
If you really wanted to be able to do chips_cart << socks
you could implement the <<
method:
class Cart < ApplicationRecord
# ...
def <<(item)
items << item
end
end
Thats because the shovel operator like many operators in Ruby is really just syntactic sugar for a method call.