acts_as_votable gem routes error - ruby-on-rails

i'm new to rails and trying to get upvotes for questions working using the acts_as_votable gem. I am getting the following error telling me i have no route matches:
No route matches [GET] "/questions/1/like"
Here is my upvote method in my questions_controller.rb:
def upvote
#question = Question.find params[:question_id]
#question.liked_by current_user
redirect_to #questions
end
My routes.rb file:
resources :comments do
resources :questions
member do
put "like", to: "questions#upvote"
end
end
and my upvote button:
<%= link_to "Upvote", like_question_path(#comment, #question, method: :put) %>
Thanks for the help!

The path name like_question_path is incorrect. It should contain at least "comment", something like "like_comment_question_path". Please consult your $rake routes for accurate name.
By the way, is there any reason you need to use put? In my opinion this action is not to change existing data but add a new one, so 'POST' should be more appropriate.

Try this:
routes.rb
resources :comments do
resources :questions do
put "like", to: "questions#upvote"
end
end
Upvote button:
<%= link_to "Upvote", comment_question_like_path(#comment, #question), method: :put %>
You need the correct path, and also the method for link_to to use goes after the second parameter.

The method option should be outside of the named route, like this:
<%= link_to "Upvote", like_question_path(#comment, #question), method: :put %>
Also, what #Billy Chan said.

Related

Rails has_many through association delete path

I have a place model and a user model and a user_place model, user_place belongs to user and place both. Traditional has_many through association.
I have a page where you can view the users associated with a place. My routes look like:
resources :places do
resources :user_places
end
which generates these routes:
place_user_places GET /places/:place_id/user_places(.:format) user_places#index
POST /places/:place_id/user_places(.:format) user_places#create
new_place_user_place GET /places/:place_id/user_places/new(.:format) user_places#new
edit_place_user_place GET /places/:place_id/user_places/:id/edit(.:format) user_places#edit
place_user_place GET /places/:place_id/user_places/:id(.:format) user_places#show
PATCH /places/:place_id/user_places/:id(.:format) user_places#update
PUT /places/:place_id/user_places/:id(.:format) user_places#update
DELETE /places/:place_id/user_places/:id(.:format)
I don't love this but I'm ok with it for now.
But whenever I try to delete a user_place I have all sorts of issues.
<%= link_to "delete", place_user_place_url(place_id: #user_place.place_id, id: #user_place.id), method: 'delete' %>
No route matches {:action=>"show", :controller=>"user_places", :id=>nil, :place_id=>2}, possible unmatched constraints: [:id]
I had this working previously with slightly different routes and an actual form:
resources :places do
resources :user_places, as: 'user', only: %i[index create new]
delete 'remove_user', to: 'user_places#remove_user'
end
<% if user != current_user %>
<%= form_with model: #user_place, url: place_remove_user_path(#place.id), method: 'delete' do |form| %>
<%= form.hidden_field :user_id, value: user.id %>
<%= form.hidden_field :place_id, value: #place.id %>
<%= form.submit "delete" %>
<% end %>
<% end %>
But this feels hacky, I don't think I should need a specific form, and this was leading the form to be submitted with javascript which I don't want.
What might be a solution is to use shallow nesting in the routes (shallow: true).
resources :places do
resources :user_places, shallow: true
end
Make sure to run rails routes again. The delete method of a user_place will no longer be nested.
You can then simply delete the user_place passing a single variable (an instance of a user place, #user_place). There is no need to set the id (place_id or id) as Rails is smart enough to handle that. Just passing an instance variable is enough for the delete method to find the corresponding record.
<%= link_to "delete", user_place_url(#user_place), method: 'delete' %>

How to Write link_to for acts_as_votable nested resources?

I am trying to add voting to my site. I have improvements that are created and displayed inside of the projects show page. I'm trying to allow users to vote on improvements but I am getting an error that I think is related to how I'm linking the like button.
in my routes.rb file:
resources :projects do
resources :improvements do
member do
put "like" => "improvements#upvote"
put "unlike" => "improvements#downvote"
end
end
end
In my view:
<%= link_to like_improvement_path(improvement), class: "like", method: :put do %>
Rails recommended me to write:
<%= link_to project_like_improvement_path(improvement), class: "like", method: :put do %>
But this doesn't work. So I tried doing this in my routes.rb:
resources :projects do
resources :improvements
end
resources :improvements do
member do
put "like" => "improvements#upvote"
put "unlike" => "improvements#downvote"
end
end
Using the original link_to, the voting works, but clicking on the vote button takes me to the improvements show page. I want to stay on the projects page.
If:
<%= link_to like_improvement_path(improvement), class: "like", method: :put do %>
Works then in the improvements controller's (upvote?) action simply do a:
redirect_to projects_path
At the end of whatever else you do model wise.
Change "projects_path" to the correct route for the page.
I had the same problem. The solution with your original routes.rb:
<%= link_to like_project_improvement_path(improvement.project, improvement), class: "like", method: :put do %>
You can write a redirect_to inside the upvote and downvote methods in the improvements controller.

No route matches [PUT] "/articles" but I included the put route in routes

Hi I'm new to rails and MVC but I'm trying really hard to learn. Right now I'm using AASM to make a transition from in_draft to published.
I'm being able to make the change in rails console but when trying to use a link_to I got the error in the question
`#/app/views/welcome/dashboard.html.erb
<% if article.may_publish? %>
<%= link_to 'Publish', '/articles/#{article.id}/publish', method: :put, class: "alert-link" %>
<%end%>
This is mi route
put '/articles/:id/publish', to: 'articles#publish'
And my articles_controller publish method
def publish
#article.publish!
redirect_to #article
end
you are really, really close! You need to use double quotes to be able to infer using #{}.
<%= link_to 'Publish', '/articles/#{article.id}/publish', method: :put, class: "alert-link" %>
should be:
<%= link_to 'Publish', "/articles/#{article.id}/publish", method: :put, class: "alert-link" %>
Welcome to rails. I would like to suggest you to use member for adding a RESTful put action. Rails routing
resources :articles do
put :publish, on: :member
end
To resolve your current given route problem, Please as: :public_article.
put '/articles/:id/publish', to: 'articles#publish', as: :public_article
Enjoy

How to link to controller method

I'm following this answer on how to clone a record.
I can't though workout how to phrase the link and route it.
It is in my #miniature show view so I thought it should be something like
<%= link_to 'clone', :controller => :miniatures_controller, :action => :clone %>
and the route
match 'clone', to: 'miniatures#clone', via: 'get'
but this is clearly wrong. I am using #miniature in place of the above answer's #prescription.
What if you just use clone_path:
<%= link_to 'clone', clone_path %>
Cause rake routes shows just clone route. It works with the same routes.
If you are not satisfied with route and you should pass parameters (like miniature_id), add member to your resource (probably nested), like:
resources :miniatures do
member do
get 'clone'
end
end
This will be clone_miniature_path where you should pass #miniature:
<%= link_to 'clone', clone_miniature_path(#miniature) %>

Route to controller action

I created an form_tag form:
<%= form_tag(set_image_dokumente_path) do %>
<%= text_field_tag :shit,'', data: {autocomplete_source: search2_patients_path}, :class => "shit" %>
<% end %>
I try to route to set_image action of dokumente controller, but i get the error:
undefined local variable or method `set_image_dokumente_path' for #<#<Class:0x711ff60>:0x762d578>
By default my form_tag goes to dokumente controller index action!
My routes:
resources :images
get "dokumente/index"
post "dokumente/index"
match 'patients/list' => 'patients#list'
resources :patients do
collection do
get :search2
end
end
How do i have to change it?
You can add the as: parameter to you route in order to create a named path.
For example:
post "dokumente/index", as: 'set_image_dokumente'
or similar, I'm not sure what you are trying to achieve, but I hope you get the idea :)
More info:
http://guides.rubyonrails.org/routing.html#generating-paths-and-urls-from-code

Resources