views:

284

answers:

1

Hi,

I have two models, one called Notes and one called Comments. Comments can be associated to many other models so I use a polymorphic association. In the schema.rb it looks like this:

  create_table "comments", :force => true do |t|
t.text     "body"
t.integer  "user_id"
t.integer  "commentable_id"
t.integer  "commentable_type"
t.datetime "created_at"
t.datetime "updated_at" end

When I want to save a comment to a note everything seems to work:

    # POST /comments
  # POST /comments.xml
  def create
    @comment = Comment.new(params[:comment])
    @comment.user = current_user
    respond_to do |format|
      if @comment.save
        process_file_uploads
        flash[:notice] = 'Comment was successfully created.'
        if !params[:note_id].nil?
          @note = Note.find(params[:note_id])
          debugger
          @note.comments << @comment
          format.html { redirect_to(@note) }
          format.xml  { render :xml => @note, :status => :created, :location => @note }
        else
          format.html { redirect_to(@comment) }
          format.xml  { render :xml => @comment, :status => :created, :location => @comment }
        end
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @comment.errors, :status => :unprocessable_entity }
      end
    end
  end

The strange thing is that in the comment table it saves commentable_type = 0 and not = "Note" as it should be. It still finds the comments if I enter @note.comments.

Comment Update (0.4ms)   UPDATE `comments` SET `commentable_type` = 0, `commentable_id` = 11, `updated_at` = '2009-04-03 10:55:50' WHERE `id` = 5

I don't understand this behaviour. Do you have any ideas?

+1  A: 

Hi, you're very close! Just change your commentable_type column to be a string instead of an integer and it should get populated correctly (assuming your model declarations are correct of course). For reference I'll include an example of how this should be set up:

# Comment model
class Comment < ActiveRecord::Base
  belongs_to :commentable, :polymorphic => true
end

# Other models which can contain comments
class AnotherModel < ActiveRecord::Base
  has_many :comments, :as => :commentable
end

class YetAnotherModel < ActiveRecord::Base
  has_many :comments, :as => :commentable
end

Also for anyone in this situation, here's a migration that will make the change:

class ChangeCommentableTypeToString < ActiveRecord::Migration
  def self.up
    change_column(:comments, :commentable_type, :string)
  end

  def self.down
    change_column(:comments, :commentable_type, :integer)
  end
end
Adam Alexander
OMG! That is so embarassing.... I can't believe it. Sometimes one looks for the complex solutions and misses the basic thinks. Doh!Thanks!
ole_berlin
It happens to all of us! I just added a migration in case it helps you or anyone.
Adam Alexander