ruby - What is the Rails way to work with polymorphic associations? -


i have few models in rails application, are:

  1. user
  2. photo
  3. album
  4. 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

Popular posts from this blog

php - Wordpress website dashboard page or post editor content is not showing but front end data is showing properly -

How to get the ip address of VM and use it to configure SSH connection dynamically in Ansible -

javascript - Get parameter of GET request -