ruby - What is the Rails way to work with polymorphic associations? -
i have few models in rails application, are:
- user
- photo
- album
- comment
i need make comments belog either photo
or album
, , belong user
. i'm going use polymorphic associations that.
# models/comment.rb class comment < activerecord::base belongs_to :user belongs_to :commentable, :polymorphic => true end
the question is, rails way describe #create
action new comment. see 2 options that.
1. describe comment creation in each controller
but ths not dry solution. can make 1 common partial view displaying , creating comments have repeat myself writing comments logic each controller. doesn't work
2. create new commentscontroller
this right way guess, aware:
to make work, need declare both foreign key column , type column in model declares polymorphic interface
like this:
# schema.rb create_table "comments", force: :cascade |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 writing pretty simple controller, accepting requests remote form:
# controllers/comments_controller.rb class commentscontroller < applicationcontroller def new @comment = comment.new end def create @commentable = ??? # how commentable id , type? if @comment.save(comment_params) respond_to |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) end end
how commentable_id
, commetable_type
? guess, commentable_type
might model name.
also, best way make form_for @comment
other views?
you'll best nesting in routes, delegating parent class:
# config/routes.rb resources :photos, :albums resources :comments, only: :create #-> url.com/photos/:photo_id/comments end # app/controllers/comments_controller.rb class commentscontroller < applicationcontroller def create @parent = parent @comment = @parent.comments.new comment_params @comment.save end private def parent album.find params[:album_id] if params[:album_id] photo.find params[:photo_id] if params[:photo_id] end def comment_params params.require(:comment).permit(:body).merge(user_id: current_user.id) end end
this fill out automatically you.
in order give @comment
object, you'll have use:
#app/controllers/photos_controller.rb class photoscontroller < applicationcontroller def show @photo = photo.find params[:id] @comment = @photo.comments.new end end #app/views/photos/show.html.erb <%= form_for [@photo, @comment] |f| %> ...
Comments
Post a Comment