I have two models:
Exercise, and Step. Exercise has many steps.
Basically, when I add a step to a new exercise's "steps" array, it
saves, and everything works. If I then get the exercise from the model
(via find), clear its array, then add the step again, I cannot save
the step to the exercise. Here is a console dump which shows exactly
what happens:
----------
a = Exercise.new
=> #<Exercise id: nil, name: nil, description: nil, image: nil,
created_at: nil,
updated_at: nil>
a.name = "The Name"
=> "The Name"
b = Step.new
=> #<Step id: nil, description: nil, picture: nil, number: nil,
exercise_id: nil
, created_at: nil, updated_at: nil, name: nil>
c = Step.new
=> #<Step id: nil, description: nil, picture: nil, number: nil,
exercise_id: nil
, created_at: nil, updated_at: nil, name: nil>
a.save
=> true
b.save
=> true
c.save
=> true
a.steps << b
=> [#<Step id: 35, description: nil, picture: nil, number: nil,
exercise_id: 26,
created_at: "2009-01-06 02:26:36", updated_at: "2009-01-06 02:26:38",
name: nil
]
a.steps << c
=> [#<Step id: 35, description: nil, picture: nil, number: nil,
exercise_id: 26,
created_at: "2009-01-06 02:26:36", updated_at: "2009-01-06 02:26:38",
name: nil
, #<Step id: 36, description: nil, picture: nil, number: nil, exercise_id: 26,
created_at: "2009-01-06 02:26:36", updated_at: "2009-01-06 02:26:40",
name: nil>
]
a.save
=> true
a = Exercise.find_by_name("The Name")
=> #<Exercise id: 26, name: "The Name", description: nil, image: nil,
created_at
: "2009-01-06 02:26:35", updated_at: "2009-01-06 02:26:35">
a.steps
=> [#<Step id: 35, description: nil, picture: nil, number: nil,
exercise_id: 26,
created_at: "2009-01-06 02:26:36", updated_at: "2009-01-06 02:26:38",
name: nil
, #<Step id: 36, description: nil, picture: nil, number: nil, exercise_id: 26,
created_at: "2009-01-06 02:26:36", updated_at: "2009-01-06 02:26:40",
name: nil>
]
a.steps.clear()
=>
a.steps << b
=> [#<Step id: 35, description: nil, picture: nil, number: nil,
exercise_id: 26,
created_at: "2009-01-06 02:26:36", updated_at: "2009-01-06 02:26:38",
name: nil
]
a.steps << c
=> [#<Step id: 35, description: nil, picture: nil, number: nil,
exercise_id: 26,
created_at: "2009-01-06 02:26:36", updated_at: "2009-01-06 02:26:38",
name: nil
, #<Step id: 36, description: nil, picture: nil, number: nil, exercise_id: 26,
created_at: "2009-01-06 02:26:36", updated_at: "2009-01-06 02:26:40",
name: nil>
]
a.save
=> true
b.save
=> true
c.save
=> true
a = Exercise.find_by_name("The Name")
=> #<Exercise id: 26, name: "The Name", description: nil, image: nil,
created_at
: "2009-01-06 02:26:35", updated_at: "2009-01-06 02:26:35">
a.steps
=>
----------
What is going on here? This is so anti-intuitive - how could a bug
like this exist and not have been detected hundreds of times before?
Yes, I would regard this as a Rails bug.
The clear method is not setting the foreign key to
nil on the in-memory object.
It's only being manifest though because of the
unnecessary saves you're doing, meaning that
the problem has probably been rarely seen.