No routes match error - ruby-on-rails

Not sure why I'm getting
No route matches {:action=>"edit", :controller=>"documents"}
in a link_to in one of my partials
relevant routes.rb
resources :documents, only: [:create, :destroy, :edit, :update] do
post 'sort' => 'documents#sort', on: :collection
end
I recently just added the edit and update actions and thus my current issues
rake routes =
sort_documents POST /documents/sort(.:format) documents#sort
documents POST /documents(.:format) documents#create
edit_document GET /documents/:id/edit(.:format) documents#edit
document PUT /documents/:id(.:format) documents#update
DELETE /documents/:id(.:format) documents#destroy
The partial with the problem route is just
<%= document.title %>
<%= document.position %>
<%= link_to 'link_to_test', edit_document_path %>
<%= link_to 'Delete', document, method: :delete, remote: true %>
my documents_controller.rb has
edit defined
def edit
#document = current_user.documents.find(params[:id])
end

The error occurs because you forgot to specify the object or its id in the edit_document_path. Try this:
<%= link_to 'link_to_test', edit_document_path(document) %>

Related

The action 'destroy' could not be found for ListingsController

UPDATE - I'VE NOW SOLVED THIS PROBLEM - I created a partial for the each Course item and rendered them from the main listing view. Thanks for all your help, I'm not really sure why it worked but it did END OF UPDATE
Apologies if this looks like a repeat posting but I've tried applying solutions to similar questions and they haven't worked, I'm stuck! Any suggestions welcomed, thank you.
Problem
I have a 'Courses' model which belongs to a 'Listings' model. The courses are created and deleted on a page belonging to Listing i.e. "/listing/2/courses"
Error Message
No route matches [DELETE] "/listings/2/courses"
Courses Controller def destroy detail
class CoursesController < ApplicationController
before_action :authenticate_user!, except: [:show]
before_action :set_listing
before_action :set_course, except: [:index, :new, :create]
def destroy
#course = #listing.courses.find(params[:id])
#course.destroy
flash[:notice] = "Course deleted!"
redirect_back(fallback_location: request.referer)
end
private
def set_course
#listing = Listing.find(params[:listing_id])
#course = Course.find(params[:id])
end
def set_listing
#listing = Listing.find(params[:listing_id])
end
def course_params
params.require(:course).permit(:name, :curriculum_type, :summary, :address, :course_places, :start_date, :finish_date, :price)
end
end
listing/listingID/courses page detail
<%= #listing.courses.each do |f| %>
<div class="jumbotron">
<ul>
<li>Name = <%= f.name %></li>
<li>Type of course = <%= f.curriculum_type %></li>
<li>Number of places = <%= f.course_places %></li>
<li>Start Date = <%= f.start_date %></li>
<li>Finish Date = <%= f.finish_date %></li>
<li>Price (£) = <%= f.price %></li>
<%= link_to "Delete Course", listing_courses_path(#listing, #course), method: :delete %>
</ul>
</div>
<% end %>
Routes.rb detail
resources :users, only: [:show]
resources :listings, except: [:edit] do
member do
get 'listing'
get 'pricing'
get 'description'
get 'photo_upload'
get 'amenities'
get 'location'
get 'courses'
end
resources :courses, except: [:edit] do
member do
get 'listing'
get 'pricing'
get 'description'
get 'photo_upload'
get 'amenities'
get 'location'
end
end
end
<%= link_to listing_course_path(#listing,f), :method => :delete, :data => { :confirm => 'Are you sure?' } %>
or try
<%= link_to listing_course_path(#listing,id: f.try(:id)), :method => :delete, :data => { :confirm => 'Are you sure?' } %>
route.rb
resources :listings do
resources :courses
end
By default, destroy method expects an ID as it's a member route. You are using listing/listingID/courses route without an ID. For that you need to define listing and/or courses as singular resources (read this) like:
resource :courses do
:
end
as described in this answer or make destroy a collection route like so:
resources :courses, except: [:edit] do
delete :destroy, on: :collection
:
rest...
end
Try and see if this works.
By the way, this looks a bit redundant as you are iterating over each #listing.courses and calling courses#destroy where you are destroying all the courses of #listing anyhow. So, why do #listing.courses.each in the first place. You should have either used a listing#destroy_courses method or remove #listing.courses.each iteration.
Update path in link_to to listing_course_path(#listing, #course) from listing_courses_path(#listing, #course)
<%= link_to "Delete Course", listing_course_path(#listing, f), method: :delete %>

Rails 4.2.5 link_to delete method

I have problem with a nested delete method for a link_to helper.
Here are my routes:
resources :restaurants, only: [:new, :show, :edit, :index,:create] do
resources :reservations, only: [:new, :show, :edit, :index, :create]
resources :reviews
end
Here is my review controllers action:
def destroy
#review = Review.find(params[:id])
#review.destroy
end
and my code on user#show:
<div class="panel-body">
<h1> <%= pluralize(#user.reviews.count ,'review') %> from <%= #user.name %> </h1>
<% #user.reviews.order(created_at: :desc).each do |review| %>
<ul>
<li><em>Review for restaurant: </em><%= review.restaurant.name %></li>
<em>Review comment: </em> <%= review.comment %></br>
<%= link_to 'edit comment', edit_restaurant_review_path(review.restaurant_id, review.id) %>
<%= link_to 'delete comment', restaurant_review_path( #user, review.id ) , method: :delete, data:{confirm:"are you sure you want to delete this review"} %>
</ul>
<% end %>
</div>
Here is my route:
restaurant_reviews GET /restaurants/:restaurant_id/reviews(.:format) reviews#index
POST /restaurants/:restaurant_id/reviews(.:format) reviews#create
new_restaurant_review GET /restaurants/:restaurant_id/reviews/new(.:format) reviews#new
edit_restaurant_review GET /restaurants/:restaurant_id/reviews/:id/edit(.:format) reviews#edit
restaurant_review GET /restaurants/:restaurant_id/reviews/:id(.:format) reviews#show
PATCH /restaurants/:restaurant_id/reviews/:id(.:format) reviews#update
PUT /restaurants/:restaurant_id/reviews/:id(.:format) reviews#update
DELETE /restaurants/:restaurant_id/reviews/:id(.:format) reviews#destroy
I can't seem to delete my reviews. Am I passing in the wrong variables?
to 'restaurant_review_path'? My route seems to be right. as my edit link_to helper is working.
restaurant_review_path( #user, review.id ) is wrong. You're passing #user as the restaurant argument, which is going to produce a link with the wrong ID.
You should be giving it a restaurant (or restaurant ID) and a review, not a user and a review id, just like you're doing on the previous line with the edit link.
restaurant_review_path(review.restaurant_id, review.id)

No route matches [PUT] but I included "resources" in routes.rb

I'm coding a blog that has two types of articles: "drafts" and "published". I'm using the aasm gem for making the article transition from draft to published or viceverza. There are also three types of users: "regular readers", "editors" and "admins".
As users write articles, admins can evaluate whether to publish them or not. To accomplish this, admins have a view in which they can see both drafts and published articles.
The problem is that when I try to publish the articles I get the No route matches [PUT] "/articles" error, regardless I've added resources :articles in routes.rb.
The code I wrote is the following:
routes.rb
resources :categories
resources :articles do
resources :comments, only: [:create, :update, :destroy, :show]
end
devise_for :users
root 'welcome#index'
get '/dashboard', to: 'welcome#dashboard'
put '/articles/:id/publish', to: 'articles#publish'
articles_controller.rb
...
def publish
#article.publish! # Article transition from draft to published.
redirect_to #article
end
...
dashboard.html.erb
...
<% #articles.each do |art| %>
<h1><%= link_to art.title, art, method: :get %> | id = <%= art.id %> | user_id = <%= art.user_id %></h1>
<div>
<%= art.body %> - <%= link_to "Eliminar", art, method: :delete %>
<% if art.may_publish? %>
- <%= link_to "Publicar", '/articles/#{article.id}/publish' , method: :put %>
<% end %>
</div>
<% end %>
...
I can't see why I get this error if I included the article resource. If you need me to include more code don't hesitate to ask me.
Thanks in advanced.
You should remove your custom routes and put it into resources :articles like this :
routes.rb
resources :articles do
put 'publish', on: :member
resources :comments, only: [:create, :update, :destroy, :show]
end
and you should use this in your view :
<%= button_to "Publicar", publish_article_path(article), method: :put %>
It will generate a form.
The code seems to be correct, so try to reset the server and, by the way, restart the browser. It usually solves strange problems like this :) Let me know if it worked.

rendering a partial fails only on ajax

My code is rather similar in concept to the railstutorial by Michael Hartl - the following users part, however it is different enough to ask this question.
The problem before all the details:
When I remove the remote: true from _like, everything works smoothly,
When _like.html.erb has remote: true I'm getting:
No route matches {:action=>"destroy", :controller=>"likes", :artwork_id=>1} missing required keys: [:id]
And I don't understand why.
The code snippets:
views/artworks
show.html.erb:
<div id="like_link">
<% if #artwork.liked_users.include?(current_user) then %>
<%= render 'unlike' %>
<% else %>
<%= render 'like' %>
<% end%>
</div>
_unlike.html.erb:
<%= link_to 'UNLike', like_path(artwork_id: #artwork.id), method: :delete, remote: true %>
_like.html.erb:
<%= link_to 'Like', likes_path(artwork_id: #artwork.id), method: :post, remote: true %>
views/likes
create.js.erb:
$("#like_link").html("<%= escape_javascript(render("artworks/unlike")) %>")
$("#likes").html('<%= #artwork.likes_count %>')
destroy.js.erb:
$("#like_link").html("<%= escape_javascript(render("artworks/like")) %>")
$("#likes").html('<%= #artwork.likes_count %>')
and the likes controller - controllers/likes_controller.rb
class LikesController < ApplicationController
respond_to :html, :js
def create
#artwork = Artwork.find(params[:artwork_id])
current_user.like!(#artwork)
respond_with #artwork
end
def destroy
#artwork = Artwork.find(params[:artwork_id])
current_user.unlike!(#artwork)
respond_with #artwork
end
end
routes.rb:
resources :artworks
resources :likes, only: [:create, :destroy]
here you create routes of
resources :likes, only: [:create, :destroy]
According RAILS convention it create routes for likes controller there it use :id such as "likes/:id" not likes/artwork_id so please create likes routes manually or follow convention.
Here is the problematic line:
# _like.html.erb
<%= link_to 'Like', likes_path(artwork_id: #artwork.id), method: :post, remote: true %>
The problem here is likes_path(artwork_id: #artwork.id), method: :post. If you check the output of rake routes you should see the following two lines for your likes resources:
likes POST /likes(.:format) likes#create
like DELETE /likes/:id(.:format) likes#destroy
As you can see the likes_path does not take in a parameter except the format, so your likes_path(artwork_id: #artwork.id) cannot be mapped to any path.
You should update your route definition with the following:
# app/config/routes.rb
resources :artworks do
resources :likes, only: [:create, :destroy]
end
With this route definition, your link_to calls will be:
# _like.html.erb
<%= link_to 'Like', artwork_likes_path(artwork_id: #artwork.id), method: :post, remote: true %>
# _unlike.html.erb
# Replace this_like_id with like_id attribute for this like being destroyed.
<%= link_to 'UNLike', artwork_likes_path(artwork_id: #artwork.id, id: this_like_id), method: :delete, remote: true %>
you do not have o pass artwork id
<%= link_to 'Like', likes_path(#artwork), method: :post, remote: true %>
<%= link_to 'UNLike', like_path(#artwork), method: :delete, remote: true %>
and now you can access this in controller by
params[:id]

Rails 3 : Can't get form_for to work as a 'delete' following the RESTful achitecture => always giving a ROUTING ERROR

I have a very simple render that goes as follow:
<%= form_for(:relationships, :url => relationships_path, :html => {:method => 'delete'}) do |f| %>
<div><%= f.hidden_field :user_id_to_unfollow, :value => #user.id %></div>
<div class="actions"><%= f.submit "Unfollow" %></div>
<% end %>
When I submit this form it will always give me a
Routing Error
No route matches "/relationships"
on my page.
In my relationships controller, I have created all the propers methods:
def create
...
end
def destroy
...
end
def update
...
end
def show
...
end
And in my routes config I have made sure to allow all routes for the relationships controller
resources :relationships
But I can't seem to get into the destroy method of the controller :(
However if I remove the
:html => {:method => 'delete'}
method parameter in the form_for then I get to the create method of the controller no pb.
I don't get it....
Alex
ps: this is the rake routes results for relationships:
relationships GET /relationships(.:format) {:action=>"index", :controller=>"relationships"}
POST /relationships(.:format) {:action=>"create", :controller=>"relationships"}
You should point the delete request to single resource url eg. relationships/4325. Run rake routes to view what url/verb combinations are valid.
--edit
Routes for relationship resources:
resources :relationships, :only => [:index, :create, :destroy]
Unfollow button (creates a form for itself):
= button_to "Unfollow", relationship_path(relationship), :method => 'delete'

Resources