'"undefined method `each'" occurs in one-to-many association in Rails console
I created a association between two Models: User and Task, User has_many Tasks, and Task belongs_to User. In theory, this will generate User.tasks and User.tasks= these new methods can be used. However, when I execute the tests in the Rails console, I have an inexplicable problem:
> u1 = User.find_by_id(1)
> t1 = Task.new(name:"MY NEW TASK")
> u1.tasks = t1
Traceback (most recent call last):
2: from (irb):7
1: from (irb):7:in `rescue in irb_binding'
NoMethodError (undefined method `each' for #<Task:0x00007f2f0446f570>
Does this mean there is something wrong with the association between the two Models? How should I fix it?
Solution 1:[1]
When you declare a has_many assocation the others= setter it creates expects the value to be an array, ActiveRecord::Relation or generally any object that responds to #each. Its is after all an assocation with MANY other objects - not a single object.
It would work if you actually wrote:
u1 = User.find_by_id(1)
t1 = Task.new(name:"MY NEW TASK")
u1.tasks = [t1]
But thats not very idiomatic and will remove any other tasks which you probably don't want.
The idiomatic way to create a unsaved record off a has_many assocation is:
u1 = User.find_by_id(1)
t1 = u1.tasks.new(name:"MY NEW TASK")
If you want to add a single existing record to an assocation on an object you can use the "shovel" method:
u1 = User.find_by_id(1)
t1 = Task.new(name:"MY NEW TASK")
u1.tasks << t1
This will save the record though.
Solution 2:[2]
You can provide the user directly when you create a task:
u1 = User.find_by_id(1)
t1 = Task.new(name:"MY NEW TASK", user: u1)
Alternatively, create a task via u1.tasks:
u1.tasks.create(name:"MY NEW TASK")
You should consider adding a validator to require a task is always created with a user. I assume that it doesn't make sense to create tasks that aren't assigned to a user. A validator can enforce this so you get an error when you try to create a task without a user.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | max |
| Solution 2 | Code-Apprentice |
