.save puts NULL in id field in Rails
Here's the model file:
class ProfileTag < ActiveRecord::Base
def self.create_or_update(options = {})
id = options.delete(:id)
record = find_by_id(id) || new
record.id = id
record.attributes = options
puts "record.profile_id is"
puts record.profile_id
record.save!
record
end
end
This gives me the correct print out in my log. But it also says that there's a call to UPDATE that sets profile_id
to NULL
. Here's some of the output in the log file:
Processing ProfilesController#update (for 127.0.0.1 at 2010-05-28 18:20:54) [PUT]
Parameters: {"commit"=>"Save", "profile"=>{"id"=>"2", "password_confirmation"=>"", "username"=>"user2", "first_name"=>"user2_first", "password"=>"", "last_name"=>"user2_last"}, "authenticity_token"=>"...", "tag"=>"1", "id"=>"2"}
?[4;36;1mProfileTag Create (0.0ms)?[0m ?[0;1mINSERT INTO `profile_tags`
(`reputation_value`, `updated_at`, `tag_id`, `id开发者_Python百科`, `profile_id`, `created_at`) VALUES(0, '2010-05-29 01:20:54', 1, NULL, 4, '2010-05-29 01:20:54')?[0m
?[4;35;1mSQL (2.0ms)?[0m ?[0mCOMMIT?[0m
?[4;36;1mSQL (0.0ms)?[0m ?[0;1mBEGIN?[0m
?[4;35;1mSQL (0.0ms)?[0m ?[0mCOMMIT?[0m
?[4;36;1mProfileTag Load (0.0ms)?[0m ?[0;1mSELECT * FROM `profile_tags` WHERE (`profile_tags`.profile_id = 4) ?[0m
?[4;35;1mSQL (1.0ms)?[0m ?[0mBEGIN?[0m
?[4;36;1mProfileTag Update (0.0ms)?[0m ?[0;1mUPDATE `profile_tags` SET profile_id = NULL WHERE (profile_id = 4 AND id IN (35)) ?[0m
I'm not sure I understand why the INSERT
puts the value into profile_id
properly, but then it sets it to NULL
on an UPDATE
.
[Edit] In ProfileController:
def update
#...stuff. Set tags array.
save_tags(tags) #These tags are correct. Verified by printouts before and after this call.
respond_to do |format|
if @profile.update_attributes(params[:profile])
flash[:notice] = 'Profile was successfully updated.'
#format.html { redirect_to(@profile) }
format.html { redirect_to :action=>'show' }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @profile.errors, :status => :unprocessable_entity }
end
end
end
def save_tags(tags)
profile = find_profile #finds the correct profile. And I confirm that it exists with a printout
tags.each do |t|
ProfileTags.create_or_update(:profile_id => profile.profile_id, :tag_id => t.id)
end
end
If you need more specifics, please let me know. I'm thinking that the save
functionality does many things other than INSERT
s into the database, but I don't know what I need to specify so that it will properly set profile_id
.
Look at the line:
ProfileTags.create_or_update(:profile_id => profile.profile_id, :tag_id => t.id)
I believe you want to pass profile.id
, and not profile.profile_id
(which is probably null).
save! itself should't do this.
Maybe your problem is the name of the method. ActiveRecord::Base already have a method named create_or_update (see http://github.com/rails/rails/blob/2-3-stable/activerecord/lib/active_record/base.rb#L2913) which is called by save! - maybe replacing it causes this weird problem.
Try changing the name of your method to something else, it might help.
You aren't passing the id attribute to the create_or_update method in the first place, so you don't need to call it, just call create instead, like so:
def save_tags(tags)
profile = find_profile #finds the correct profile. And I confirm that it exists with a printout
tags.each do |t|
ProfileTag.create(:profile_id => profile.profile_id, :tag_id => t.id)
end
end
精彩评论