No route matches [GET] "/links/1/like" with acts_as_votable - ruby-on-rails

I'm trying to implement acts_as_votable gem as shown in this this tutorial
https://www.youtube.com/watch?v=7-1HCWbu7iU
Seems everything is workigng fine, except when I click on upvote or downvote, I get this error:
No route matches [GET] "/links/1/like"
This is the code for upvote / downvote function
<span class="upvote">
<%= link_to like_link_path(link), method: :put, class: "upvote-image" do %>
<% end %>
</span>
This is the routes.rb file:
resources :links do
member do
put "like", to: "links#upvote"
put "dislike", to: "links#downvote"
end
resources :comments
end
Here are the upvote and downvote actions in links_controller
def upvote
#link = Link.find(params[:id])
#link.upvote_by current_user
redirect_to :back
end
def downvote
#link = Link.find(params[:id])
#link.downvote_by current_user
redirect_to :back
end
Any idea on how to resolve this?

Looks like the problem is down to your link having a GET method, rather than PUT:
No route matches [GET] "/links/1/like"
I can only surmise that your link_to code is not written correctly:
<span class="upvote">
<%= link_to like_link_path(link), method: :put, class: "upvote-image" %>
</span>
Your other code looks good. If you test this, the best thing to do will be to show the pure HTML for the link in your question - this will give us the ability to see whether it's being rendered correctly.

I found an answer for this, and I'm posting it here in case there are others with the same problem.
I'm developing on Windows. I had problems with javascript, and followed this solution here:
https://stackoverflow.com/a/31972253/1690091
This removed the javascript related errors that were popping all over the place, but this is NOT the solution. This simply removed js from my app.
The real solution is here:
https://stackoverflow.com/a/28331807/1690091
You need to use a proper version of coffee script, that's compatible with Windows.
To sum things up:
js file was missing from my app, and therefore //= require jquery_ujs was also missing, and that's why all of my links were being called as GET.
#Rich Peck,
Thanks for your help.

Try this
<span class="upvote">
<%= link_to like_path, method: :put, class: "upvote-image" do %>
<% end %>
</span>

Related

Ruby on Rails Custom Controller Action for Users Controller

Working on versions:
Ruby: 3.0.2
Rails 6.1.4
I'm trying to put a button in my View template for "Users" that will set the :mod attribute to false, with the button just being "Demote User".
I had it working SOMEHOW using a helper method, demote_user, and some variation of
<% if logged_in? && current_user.admin? %>
<%= link_to "Demote User", user_path(#user), onclick: demote_user(#user), class: "btn btn-info" %>
<% end %>
I messed up however it was working when trying to move this method into a controller for best practice. I'm not sure what format worked out, but I've tried many such as
:onclick => demote_user(#user)
onclick: 'demote_user(#user)'
onclick=demote_user(#user)
onclick='demote_user(#user)
and etc. Somehow, it did eventually work but I busted it. Now, every time I load the User's page, it's just executing demote_user(#user) without even needing to click the button, so refreshing a User's page is demoting them.
I am now trying to do this properly by creating a demote method in the UserController, but I have NO IDEA how to make the route, or make it work properly. Up until now, all my routes have been working using resources, and the basic new, create, destroy, etc.
I've been trying many different routes, and view formatting, with no luck and usually ending up with just: Routing Error
No route matches [GET] "/demote.3"
I'd like to be able to avoid using the Javascript onClick functionality and do it properly with the controller even if I could remember how to make it work, but I think my route, or view page, or controller is incorrect. Here are the contents of each file:
Controller
def demote
byebug
#user = User.find(params[:id])
#user.mod = false
redirect_to user_path(#user)
end
View
div class="container text-center mt-4">
<% if logged_in? && current_user.admin? %>
<%= link_to "Demote User", demote_path(#user), class: "btn btn-info" %>
<% end %>
</div>
Routes
Rails.application.routes.draw do
root 'pages#home'
get 'about', to: 'pages#about'
resources :articles
get 'signup', to: 'users#new'
resources :users, except: [:new]
get 'login', to: 'sessions#new'
post 'login', to: 'sessions#create'
delete 'logout', to: 'sessions#destroy'
resources :categories
post 'demote', to: 'users#demote'
end
Up until now, I've been following a course, and I've nailed everything in it and have added some of my own functionality, but I'm still not quite sure how to make sense of routes, or what paths it creates.
I'd like to make other similar custom controller functions beyond show, index, create, delete, update which are all I really understand how to build. I'm not even sure if POST is the correct call in the route.
I would just setup an additional RESTful action for the resource:
resources :users do
patch :demote
end
<% if logged_in? && current_user.admin? %>
<%= button_to "Demote User", demote_user_path(#user), method: :patch %>
<% end %>
You can use link_to instead of button_to but you need to use the correct method: :patch or data: { turbo_method: :patch } option depending on your version of Rails to get the javascript driver to do its trickery.

How to use x_editable_rails for editing comments

Not sure why i am getting this error message when implementing gem x_editable_rails to allow comments to be edited without users being brought to a separate edit page.
x_editable_rails demo app shows that perhaps the right way should be <%= editable #comment, :content %>, but because I am looping all comments in the #comments instance variable, doing that throws an error too.
EDIT
I changed the line of code from <%= editable #comments.comment %> to <%= editable [comment.article, comment], :content, url: edit_article_comment_path(comment.article, comment) %> and now, its showing
undefined method `xeditable?' error.
I have added the below helper method and added this (helper_method :xeditable?) to application controller. (I don't use cancan so i have added a dummy can? as suggested on this stackoverflow post.
module ApplicationHelper
def xeditable?
current_user.xeditable?
end
def can?(role, object)
true
end
end
_comments.html.erb
<% #comments.each do |comment| %>
<%= editable [comment.article, comment], :content, url: edit_article_comment_path(comment.article, comment) %>
<%= link_to "Delete comment", [comment.article, comment], method: :delete %>
<%= link_to "Edit comment", edit_article_comment_path(comment.article, comment) %>
<% end %>
routes.rb
resources :articles do
resources :comments
end
Routing
The original error you posted indicates you do not have a route for APP_DOMAIN/comments/:id, and that's confirmed by your routes -- comment is a nested resource in your routing, routed like APP_DOMAIN/articles/:id/comments/:id.
Note that for unusual routing (i.e. not a typical Rails naming pattern), x-editable-rails allows you to specify your path. Maybe comments are routed through another name, like url: post_critique_path(#comment.post, #comment). I see you have now done this, though I'm not sure if it is necessary since your routing is standard pratice.
Note that I have not tested this myself. The README is not super clear on what are the allowed or expected values for :url. And, confusingly, the gem has a :nested option – which appears to be about setting the title HTML attribute.
Application helper methods
For your next error, it appears you are implementing the advice from this answer. But I believe you have missed a line, and your ApplicationHelper module should look like this:
module ApplicationHelper
helper_method :xeditable?, :can
def xeditable?
current_user.xeditable?
end
def can?(role, object)
true
end
end

Rails destroy does not work and forwards to a wrong link

I am totally new to rails and struggle with the easiest stuff. I have the following problem:
When I try to destroy a search (from my model search) it does not work and I get redirected to "/search.48 (the search with id 48). It gives me the notice "We're sorry, but something went wrong." and in the console it says something with POST. Neither the search is deleted nor the redirect_to search_path is working. What am I doing wrong?
This is my controller:
def show
#searches = current_user.searches
end
def destroy
#search = Search.find(params[:id])
#search.destroy
flash[:success] = "Search deleted"
redirect_to search_path
end
This is my view show:
<% #searches.each do |search| %>
<%= search.title %>
<%= search.description %>
<%= button_to "delete", search, method: :destroy %>
My routes.rb:
get 'search' => 'searches#show'
resources :searches
And I also included <%= javascript_include_tag 'application' %> in the application.html.erb as well as //= require jquery and //= require jquery_ujs in the application.js file.
So I really can't find my mistake. Can someone help me?
In your view file, the code for the button should look like:
<%= button_to "delete", search, method: :delete %>
Note the method is :delete, not :destroy. It's a little confusing, because 'delete' is the REST verb, but 'destroy' is the controller action name.
have you tried:
<%= button_to "Delete", { action: "delete", id: search.id },
method: :delete %>
in you view. Also it appears you are redirecting to search_path but I am guessing you want searches_path.
I got it! In my router I wrote get 'search' => 'searches#show' and somehow my controller was confused with the search_path. Since I renamed it to get 'mysearches' => 'searches#show' and mysearches_path it works perfectly

No route matches [GET] "/links/1/like" acts_as_votable

The other solutions here did not work, so I am posting a new question. I am using acts_as_votable for up and down voting on links, but when I try to actually vote I get the error:
No route matches [GET] "/links/1/like"
This is what my view looks like:
<%= link_to like_link_path(link), method: :put, class: "btn btn-default btn-sm" do %>
<span class="glyphicon glyphicon-chevron-up"></span>
Upvote
<%= link.get_upvotes.size %>
<% end %>
<%= link_to dislike_link_path(link), method: :put, class: "btn btn-default btn-sm" do %>
<span class="glyphicon glyphicon-chevron-down">
Downvote
<%= link.get_downvotes.size %>
<% end %>
And this is what my routes look like:
resources :links do
member do
put "like", to: "links#upvote"
put "dislike", to: "links#downvote"
end
end
I see that my client is trying to access the get method, but I explicitly call method: :put in my index.html.erb file.
Do you know why it is trying to access get and how I can override that?
This problem is almost always to do with JQuery, although in this instance I'm not sure why.
You can even see it here:
Note that if the user has JavaScript disabled, the request will fall back to using GET
I would firstly check that you have JQuery in your app, and then that it's getting called okay. If it isn't loading, then the best course of action is to see why JQuery is not being called (it's either going to because it won't be referenced, or you'll have an error preventing it from loading).
Your code actually looks valid, so I'd have to say that JQuery would be the likely issue here.
You could polish up your routes etc:
#config/routes.rb
resources :links do
match "vote", action: :vote, via: [:put,:delete], on: :member
end
This will send both types of request to an action called vote, which you can then split up as follows:
#app/controllers/links_controller.rb
class LinksController < ApplicationController
def vote
if request.put?
# Code to vote
elsif request.delete?
# Code to downvote
end
# Redirect back
end
end
Much DRYer and more efficient (only calling a single action etc)
It turns out that the answer was related to JQuery. I was getting an Uncaught ReferenceError: jQuery is not defined error and so what I did was include JQuery outright in my application.html.erb file.
You have to put this ahead of all your other scripts.
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
After that, the voting began to work

Acts as votable routing error

I'm trying to use acts as votable gem and can't understand how it actually works. I couldn't find any good workarounds or tutorials for it. I tried implementing the accepted solution mentioned here but got Routing Error. Can anyone help me out with a good tutorial or point me out how to get it to work editing the following code.
routes.rb
resources :posts do
member do
put "like", to: "posts#upvote"
end
end
posts controller
def upvote
#post = Post.find(params[:id])
#post.liked_by current_user
redirect_to #post
end
show.html.erb
<%= link_to "Bookmark Post", like_post_path(#post, method: :put), class: "button tiny" %>
method attribute should be passed to the link_to method, not the path helper, like this
<%= link_to "Bookmark Post", like_post_path(#post), method: :put, class: "button tiny" %>

Resources