I have established an association between three models, where User can has_many Recipe, and Recipe belongs_to User. This is what the model sets:
model User
has_many :reviews
has_many :recipes, through: :reviews
model Recipe
has_many :reviews
has_many :users
belongs_to :user
model Review
belongs_to :user
belongs_to :recipe
Currently, User and Recipe each have a data. I want to assign Recipe to User, so I did the following in the Rails console:
u2 = User.find_by_id(2)
r1 = Recipe.find_by_id(1)
u2.recipes = r1
Then "NoMethodError (undefined method `each’ for #Recipe:0x0000560632fde3d0)" appears.
I can’t understand, has_many or has_one should generate recipes and recipes= methods, why doesn’t this work?
>Solution :
It doesn’t work since you’re attempting to assign a single record to a has_many assocation. The reason you’re getting undefined method 'each' is that the generated setter expects an array or a an assocation that can be iterated upon. For example:
user = User.find(2)
user.recipies = Recipe.where(id: 1)
But the idiomatically correct way to assign a single record to a has_many or has_and_belongs_to_many assocation is with the shovel method:
u2 = User.find_by_id(2)
r1 = Recipe.find_by_id(1)
u2.recipes << r1
With an indirect assiation Rails will implicitly create the rows in the join table.