ruby on rails - How to Edit Polymorphic Comments? -


since comments being posted in multiple locations: habits, goals, etc. path use edit comment in comments/_comments?

i tried:

<%= link_to edit_comment_path(comment) %> #or should use conditionals target: edit_habit_comment_path, edit_goal_comment_path, etc?   <%= comment.content %> <% end %> 

but upon clicking on error:

activerecord::recordnotfound (couldn't find comment 'id'=2 [where "comments"."commentable_id" = ? , "comments"."commentable_type" = ?])

i played around put in def edit here:

comments_controller

class commentscontroller < applicationcontroller     before_action :load_commentable   before_action :set_comment, only: [:show, :edit, :update, :destroy, :like]   before_action :logged_in_user, only: [:create, :destroy]      def index         @comments = @commentable.comments     end      def new         @comment = @commentable.comments.new     end      def create         @comment = @commentable.comments.new(comment_params)         if @comment.save             redirect_to @commentable, notice: "comment created."         else             render :new         end     end      def edit     @habit = habit.find(params[:id])     @goal = goal.find(params[:id])     @commentable = @habit     @comments = @commentable.comments     @comment = current_user.comments.find(params[:id])     end      def update         @comment = current_user.comments.find(params[:id])         if @comment.update_attributes(comment_params)             redirect_to @commentable, notice: "comment updated."         else             render :edit         end     end      def destroy         @comment = current_user.comments.find(params[:id])         @comment.destroy         redirect_to @commentable, notice: "comment destroyed."     end    def     @comment = comment.find(params[:id])     @comment_like = current_user.comment_likes.build(comment: @comment)     if @comment_like.save             @comment.increment!(:likes)         flash[:success] = 'thanks liking!'     else         flash[:error] = 'two many likes'       end           redirect_to(:back)   end  private    def set_comment     @comment = comment.find(params[:id])   end      def load_commentable         resource, id = request.path.split('/')[1, 2]         @commentable = resource.singularize.classify.constantize.find(id)     end      def comment_params         params[:comment][:user_id] = current_user.id         params.require(:comment).permit(:content, :commentable, :user_id, :like)     end end 

i closely followed tutorial: http://railscasts.com/episodes/154-polymorphic-association-revised

please let me know if need further explanation or code me :)

update

i tried lot of alternatives routes:

rails.application.routes.draw    'notes/index'    'notes/new'    'notifications/index'    'auth/:provider/callback', to: 'sessions#facebook'   'auth/failure', to: redirect('/')   'signout', to: 'sessions#destroy', as: 'signout'    'password_resets/new'    'password_resets/edit'    resources :users     resources :comments   end    shallow     resources :habits       resources :comments     end     resources :goals       resources :comments     end   end     resources :notes    resources :habits     resources :notes     resources :notifications     resources :comments       resources :likes     end     resources :likes     member       post :like       post :notifications     end     resources :levels       # we'll use route increment , decrement missed days       resources :days_missed, only: [:create, :destroy]     end   end    resources :goals     resources :notes     resources :comments     member       post :like     end   end    resources :valuations     resources :notes     resources :comments     resources :notifications     member       post :like       post :notifications     end   end    resources :quantifieds     resources :notes     resources :comments     member       post :like     end   end    resources :results    resources :users    resources :account_activations, only: [:edit]    resources :activities     resources :valuations     resources :comments     resources :notifications     member       post :like       post :notifications     end   end    resources :comments     resources :comments     member       post :like     end   end    resources :password_resets,     only: [:new, :create, :edit, :update]    resources :relationships,       only: [:create, :destroy]    'tags/:tag', to: 'pages#home', as: :tag    resources :users     member       :following, :followers     end   end       'about'   => 'pages#about'      'signup'  => 'users#new'      'login'   => 'sessions#new'   post   'login'   => 'sessions#create'   delete 'logout'  => 'sessions#destroy'    root 'pages#home' end 

you may find shallow nested routes useful. basically, write

shallow   resources :goals     resources :comments   end    # ... end 

which equivalent to

resources :goals   resources :comments, only: [:index, :new, :create] end resources :comments, only: [:show, :edit, :update, :destroy]  # ... 

this means, actions absolutely need nesting nested. if want show, edit, update, or destroy comment, work other non-nested resource , able use edit_comment_path.

you need change controller accordingly, because commentable_id (i.e. goal_id) not part of url more. can still commentable via @comment.commentable (for redirection). cleanest solution have come across setting commentable in comments controller name of :commentable_id in params, opposed fiddling around request path. result in controller this:

class commentscontroller < applicationcontroller   before_action :set_commentable, only: [:index, :new, :create]   before_action :set_comment, only: [:edit, :update, :destroy, :like]    def index     @comments = @commentable.comments   end    def new     @comment = @commentable.comments.new   end    def create     @comment = @commentable.comments.new(comment_params)     if @comment.save       redirect_to @commentable, notice: "comment created."     else       render :new     end   end    def edit   end    def update     if @comment.update_attributes(comment_params)       redirect_to @comment.commentable, notice: "comment updated."     else       render :edit     end   end    def destroy     @comment.destroy     redirect_to @comment.commentable, notice: "comment destroyed."   end    def     @comment_like = current_user.comment_likes.build(comment: @comment)     if @comment_like.save       @comment.increment!(:likes)       flash[:success] = 'thanks liking!'     else       flash[:error] = 'too many likes'     end       redirect_to(:back)   end    private    def set_commentable     @commentable = find_commentable   end    # add more commentable models here   def find_commentable     if params[:goal_id]       goal.find(params[:goal_id])     elsif params[:habit_id]       habit.find(params[:habit_id])     else       fail 'unsupported commentable'     end   end    def set_comment     @comment = current_user.comments.find(params[:id])   end    def comment_params     params[:comment][:user_id] = current_user.id     params.require(:comment).permit(:content, :commentable, :user_id, :like)   end end 

Comments

Popular posts from this blog

python - TypeError: start must be a integer -

c# - DevExpress RepositoryItemComboBox BackColor property ignored -

django - Creating multiple model instances in DRF3 -