How to Write link_to for acts_as_votable nested resources? - ruby-on-rails

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.

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' %>

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

acts_as_votable gem routes error

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.

Best way to update an ActiveRecord attribute from a link

I have a Model with an attribute votes. I have a link in a view that needs to increment the value of votes - what is the best way to do this?
I am currently trying a link like:
<%= link_to 'Up', '#', :method => :voteup %>
and a voteup method in the model_controller but this isn't working.
I think the best way would be this:
In config/routes.rb:
resources :quotes do
member do
post :upvote
end
end
And your link:
<%= link_to 'Up', upvote_quote_path(#quote), :method => :post %>
Note that we use a POST request, which is more appropriate than a GET request when modifying a record.
:method is only supposed to be used to specify between POST, GET, DELETE, and PUT requests. Your second parameter of link_to should be the action you want to execute in your controller.
<%= link_to "Up", :action => :voteup %>

Making a delete confirmation page using Ruby on Rails 3

I am trying to add a new page to my RoR3 application that should display a delete confirmation of a user account. It should match the 'destroy' action in 'ROOT_RAILS/controllers/accounts_controller.rb'.
At this time my problem occurs on creating a "link_to" this page, but maybe I am wrong somewhere and my work is not completed yet.
So, what I made, is:
I created the 'ROOT_RAILS/views/accouns/delete.html.erb' file.
I updated the routes.rb like this:
resources :accounts do
collection do
get 'delete'
post 'delete'
end
end
I don't know the next steps, but now if I try to insert this code
<%= link_to 'Delete', delete_account_path(#current_account) %>
in my views, I will get this error:
undefined method `delete_account_path' for #<#<Class:0x00...>
What I have to do?
This "link_to" works, but, of course, doesn't make what I would like:
<%= link_to 'Delete', delete_users_accounts_path %>
Try the following:
config/routes.rb:
resources :accounts do
get :delete, :on => :member
end
In the view before the delete page:
<%= link_to 'Delete', delete_account_path(#current_account) %>
In the delete view(this will invoke the destroy method in your controller):
<%= link_to 'Delete', #current_account, :confirm => "Are you sure?", :method => :delete %>

Resources