I have two links (upvote and downvote) with method put like this
<%= link_to 'upvote', comment_upvote_path(comment), method: :put, remote: true, id: "comment_upvote_link" %>
<%= link_to 'downvote', comment_downvote_path(comment), mthod: :put, remote: true, id: "comment_downvote_link" %>
here is my routes file for these two links
put '/comment/upvote/:id' => "comments#upvote", as: 'comment_upvote'
put '/comment/downvote/:id' => "comments#downvote", as: 'comment_downvote'
and in the comments controller (using acts_as_commentable_with_threading gem for comments)
class CommentsController < ApplicationController
before_action :authenticate_user!
def create
commentable = commentable_type.constantize.find(commentable_id)
@comment = Comment.build_from(commentable, current_user.id, body)
if @comment.save
make_child_comment
redirect_to(:back, :notice => 'Comment was successfully added.')
else
redirect_to :back
end
end
def upvote
@comment = Comment.find(params[:id])
current_user.up_votes @comment
respond_to do |format|
format.html { redirect_to Post.find(@comment.commentable_id) }
format.js { render 'comments/votes/upvote' }
end
end
def downvote
@comment = Comment.find(params[:id])
current_user.down_votes @comment
respond_to do |format|
format.html { redirect_to Post.find(@comment.commentable_id) }
format.js { render 'comments/votes/downvote' }
end
end
private
def comment_params
params.require(:comment).permit(:body, :commentable_id, :commentable_type, :comment_id)
end
def commentable_type
comment_params[:commentable_type]
end
def commentable_id
comment_params[:commentable_id]
end
def comment_id
comment_params[:comment_id]
end
def body
comment_params[:body]
end
def make_child_comment
return "" if comment_id.blank?
parent_comment = Comment.find comment_id
@comment.move_to_child_of(parent_comment)
end
end
comment model
class Comment < ActiveRecord::Base
default_scope -> { order(created_at: :desc)}
acts_as_nested_set :scope => [:commentable_id, :commentable_type]
validates :body, :presence => true
validates :user, :presence => true
acts_as_votable
belongs_to :commentable, :polymorphic => true
# NOTE: Comments belong to a user
belongs_to :user
def score
self.get_upvotes.size - self.get_downvotes.size
end
def self.build_from(obj, user_id, comment)
new \
:commentable => obj,
:body => comment,
:user_id => user_id
end
#helper method to check if a comment has children
def has_children?
self.children.any?
end
# Helper class method to lookup all comments assigned
# to all commentable types for a given user.
scope :find_comments_by_user, lambda { |user|
where(:user_id => user.id).order('created_at DESC')
}
# Helper class method to look up all comments for
# commentable class name and commentable id.
scope :find_comments_for_commentable, lambda { |commentable_str, commentable_id|
where(:commentable_type => commentable_str.to_s, :commentable_id => commentable_id).order('created_at DESC')
}
# Helper class method to look up a commentable object
# given the commentable class name and id
def self.find_commentable(commentable_str, commentable_id)
commentable_str.constantize.find(commentable_id)
end
end
log for upvote
Started PUT "/comment/upvote/13" for ::1 at 2015-12-27 04:12:12 +0500
Processing by CommentsController#upvote as JS
Parameters: {"id"=>"13"}
[1m[35mUser Load (0.0ms)[0m SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
[1m[36mComment Load (0.0ms)[0m [1mSELECT `comments`.* FROM `comments` WHERE `comments`.`id` = 13 ORDER BY `comments`.`created_at` DESC LIMIT 1[0m
[1m[35m (0.0ms)[0m SELECT COUNT(*) FROM `votes` WHERE `votes`.`votable_id` = 13 AND `votes`.`votable_type` = 'Comment' AND `votes`.`voter_id` = 1 AND `votes`.`voter_type` = 'User' AND `votes`.`vote_scope` IS NULL
[1m[35m (0.0ms)[0m SELECT COUNT(*) FROM `votes` WHERE `votes`.`votable_id` = 13 AND `votes`.`votable_type` = 'Comment' AND `votes`.`voter_id` = 1 AND `votes`.`voter_type` = 'User' AND `votes`.`vote_scope` IS NULL
[1m[35m (0.0ms)[0m BEGIN
[1m[36m (0.0ms)[0m [1mCOMMIT[0m
[1m[35m (0.0ms)[0m SELECT COUNT(*) FROM `votes` WHERE `votes`.`votable_id` = 13 AND `votes`.`votable_type` = 'Comment' AND `votes`.`vote_flag` = 1 AND `votes`.`vote_scope` IS NULL
[1m[35m (0.0ms)[0m SELECT COUNT(*) FROM `votes` WHERE `votes`.`votable_id` = 13 AND `votes`.`votable_type` = 'Comment' AND `votes`.`vote_flag` = 1 AND `votes`.`vote_scope` IS NULL
[1m[36m (0.0ms)[0m [1mSELECT COUNT(*) FROM `votes` WHERE `votes`.`votable_id` = 13 AND `votes`.`votable_type` = 'Comment' AND `votes`.`vote_flag` = 0 AND `votes`.`vote_scope` IS NULL[0m
Rendered comments/votes/upvote.js.erb (5.0ms)
Completed 200 OK in 25ms (Views: 15.0ms | ActiveRecord: 0.0ms)
log for downvote
Started GET "/comment/downvote/13" for ::1 at 2015-12-27 04:12:34 +0500
ActionController::RoutingError (No route matches [GET] "/comment/downvote/13"):
actionpack (4.2.4) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
web-console (2.2.1) lib/web_console/middleware.rb:39:in `call'
actionpack (4.2.4) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.2.4) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.2.4) lib/rails/rack/logger.rb:20:in `block in call'
activesupport (4.2.4) lib/active_support/tagged_logging.rb:68:in `block in tagged'
activesupport (4.2.4) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (4.2.4) lib/active_support/tagged_logging.rb:68:in `tagged'
railties (4.2.4) lib/rails/rack/logger.rb:20:in `call'
actionpack (4.2.4) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.6.4) lib/rack/methodoverride.rb:22:in `call'
rack (1.6.4) lib/rack/runtime.rb:18:in `call'
activesupport (4.2.4) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
rack (1.6.4) lib/rack/lock.rb:17:in `call'
actionpack (4.2.4) lib/action_dispatch/middleware/static.rb:116:in `call'
rack (1.6.4) lib/rack/sendfile.rb:113:in `call'
railties (4.2.4) lib/rails/engine.rb:518:in `call'
railties (4.2.4) lib/rails/application.rb:165:in `call'
rack (1.6.4) lib/rack/content_length.rb:15:in `call'
puma (2.15.3) lib/puma/server.rb:541:in `handle_request'
puma (2.15.3) lib/puma/server.rb:388:in `process_client'
puma (2.15.3) lib/puma/server.rb:270:in `block in run'
puma (2.15.3) lib/puma/thread_pool.rb:106:in `call'
puma (2.15.3) lib/puma/thread_pool.rb:106:in `block in spawn_thread'
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb (5.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb (25.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb within layouts/javascript (60.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb within layouts/javascript (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb (130.0ms)
and in browser
<a id="comment_upvote_link" data-remote="true" rel="nofollow" data-method="put" href="/comment/upvote/13">upvoted</a>
<a mthod="put" id="comment_downvote_link" data-remote="true" href="/comment/downvote/13">downvote</a>
The problem is upvote link is working but downvote is not(not even showing any kind of error), but if i change downvote request method to get in routes file like this
get '/comment/downvote/:id' => "comments#downvote", as: 'comment_downvote'
then it will work. I don't know what's the problem here, if downvote is not working then upvote also should not work because they are both identical, i tries debugging it with debugger but is seems for downvote with put method control will not go into downvote action it just don't do anything.
Any help will be appreciated.
You have a typo in the downvote link:
<%= link_to 'downvote', comment_downvote_path(comment), mthod: :put, remote: true, id: "comment_downvote_link" %>
mthod -> method