Reputation: 19314
I have an update method that is not saving database records as expected.
Basically what's happening is that the arrangement_id is not saving to the timeslot table as I would expect with the method below.
From the output of my variable's after the save!
's I would think that the arrangement_id would save in the timeslot table.
Can anyone tell me why it's not and what i'm doing wrong here?
# PUT /arrangements/1
def update
success = false
@arrangement = Arrangement.find(params[:id])
# Remove arrangement id from old timeslot
old_timeslot = Timeslot.find(@arrangement.timeslot_id)
old_timeslot.arrangement_id = nil
# Save arrangement id to new timeslot
new_timeslot = Timeslot.find(@arrangement.timeslot_id)
new_timeslot.arrangement_id = @arrangement.id
p "old_timeslot = #{old_timeslot.inspect}"
p "new_timeslot = #{new_timeslot.inspect}"
old_timeslot.save!
new_timeslot.save!
p "after save old_timeslot = #{old_timeslot.inspect}"
p "after save new_timeslot = #{new_timeslot.inspect}"
@arrangement.update_attributes!(params[:arrangement])
success = true
respond_to do |format|
if success
format.html { redirect_to @arrangement, notice: 'Arrangement was successfully updated.' }
else
format.html { render action: "edit" }
end
end
end
Here's the console output:
# These are before the old_timeslot and new_timeslot variables are saved
"old_timeslot = #<Timeslot id: 17306, location_id: 3, arrangement_id: nil, timeslot: \"2014-01-10 17:00:00\", created_at: \"2013-05-20 04:03:30\", updated_at: \"2014-01-11 01:35:55\">"
"new_timeslot = #<Timeslot id: 17306, location_id: 3, arrangement_id: 839, timeslot: \"2014-01-10 17:00:00\", created_at: \"2013-05-20 04:03:30\", updated_at: \"2014-01-11 01:35:55\">"
# These are after the old_timeslot and new_timeslot variables are saved
"after save old_timeslot = #<Timeslot id: 17306, location_id: 3, arrangement_id: nil, timeslot: \"2014-01-10 17:00:00\", created_at: \"2013-05-20 04:03:30\", updated_at: \"2014-01-11 01:37:09\">"
"after save new_timeslot = #<Timeslot id: 17306, location_id: 3, arrangement_id: 839, timeslot: \"2014-01-10 17:00:00\", created_at: \"2013-05-20 04:03:30\", updated_at: \"2014-01-11 01:35:55\">"
Started PUT "/arrangements/839" for 127.0.0.1 at 2014-01-10 19:37:09 -0600
Processing by ArrangementsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"REBgw/kRwlclqS670aIcIZ1Ug6kgxr/itEevwMQO2w8=", "arrangement"=>{"family_name"=>"smith", "location_id"=>"3", "date"=>"01/10/2014", "timeslot_id"=>"17306", "need"=>"myNeed", "notes"=>"mynotes", "user_id"=>"66"}, "button"=>"", "id"=>"839"}
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
Setting Load (0.4ms) SELECT `settings`.* FROM `settings`
Arrangement Load (0.4ms) SELECT `arrangements`.* FROM `arrangements` WHERE `arrangements`.`id` = 839 LIMIT 1
Timeslot Load (0.2ms) SELECT `timeslots`.* FROM `timeslots` WHERE `timeslots`.`id` = 17306 LIMIT 1
CACHE (0.0ms) SELECT `timeslots`.* FROM `timeslots` WHERE `timeslots`.`id` = 17306 LIMIT 1
(0.1ms) BEGIN
(0.3ms) UPDATE `timeslots` SET `arrangement_id` = NULL, `updated_at` = '2014-01-11 01:37:09' WHERE `timeslots`.`id` = 17306
(53.5ms) COMMIT
(0.1ms) BEGIN
(0.2ms) COMMIT
Redirected to http://localhost:3000/arrangements/839
Completed 302 Found in 168ms (ActiveRecord: 55.5ms)
Upvotes: 1
Views: 710
Reputation: 3946
First of all it's strange that you try to do two saves of the same record in succession. As long as the id of these records are the same the second save should just overwrite the first one.
On the other hand since Rails 2.0 or so Rails has the notion of "dirty" objects and attributes. So it might well be that the assignment
new_timeslot.arrangement_id = @arrangement.id
doesn't actually change anything, if the arrangement_id
attribute already had the value of @arrangement.id
. Therefore the new_timeslot
object wouldn't get marked as 'dirty' and rails can skip the save!
as an optimization measure. Even though you updated the very same record in the DB beforehand, new_timeslot
still doesn't get marked as 'dirty', because you did that in a different instance.
So either you want to save two different records, then you should change the id of at least one to nil
(or create a new record and initialize it with the same attributes) or you only want to update the record with the new_timeslot
attributes, then there is no reason to call save!
on old_timeslot
.
Upvotes: 1