I have few models in my Rails application, which are:
- User
- Photo
- Album
- Comment
I need to make comments belog to either to Photo
or Album
, and obviously always belong to User
. I'm going to use polymorphic associations for that.
# models/comment.rbclass Comment < ActiveRecord::Base belongs_to :user belongs_to :commentable, :polymorphic => trueend
The question is, what is the Rails way to describe #create
action for the new comment. I see two options for that.
1. Describe the comment creation in each controller
But ths is not a DRY solution. I can make one common partial view for displaying and creating comments but I will have to repeat myself writing comments logic for each controller. So It doesn't work
2. Create new CommentsController
This is the right way I guess, but as I aware:
To make this work, you need to declare both a foreign key column and a type column in the model that declares the polymorphic interface
Like this:
# schema.rb create_table "comments", force: :cascade do |t| t.text "body" t.integer "user_id" t.integer "commentable_id" t.string "commentable_type" t.datetime "created_at", null: false t.datetime "updated_at", null: false end
So, when I will be writing pretty simple controller, which will be accepting requests from the remote form:
# controllers/comments_controller.rbclass CommentsController < ApplicationController def new @comment = Comment.new end def create @commentable = ??? # How do I get commentable id and type? if @comment.save(comment_params) respond_to do |format| format.js {render js: nil, status: :ok} end end end private def comment_params defaults = {:user_id => current_user.id, :commentable_id => @commentable.id, :commentable_type => @commentable.type} params.require(:comment).permit(:body, :user_id, :commentable_id, :commentable_type).merge(defaults) endend
How will I get commentable_id
and commetable_type
? I guess, commentable_type
might be a model name.
Also, what is the best way to make a form_for @comment
from other views?