开发者

.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 INSERTs 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜