I have built a simple Rails app that has posts with one/many comments.
I want to create a simple post view that allows me to view the post and associated comments. I want each comment to have links to - view, edit, delete.
However whenever I try amending the code below I get routing errors. Help?
routes.rb
resources :posts do
resources :comments
end
rake routes
post_comments GET /posts/:post_id/comments(.:format) comments#index
POST /posts/:post_id/comments(.:format) comments#create
new_post_comment GET /posts/:post_id/comments/new(.:format) comments#new
edit_post_comment GET /posts/:post_id/comments/:id/edit(.:format) comments#edit
post_comment GET /posts/:post_id/comments/:id(.:format) comments#show
PUT /posts/:post_id/comments/:id(.:format) comments#update
DELETE /posts/:post_id/comments/:id(.:format) comments#destroy
comments_controller.rb
def show
#comment = Comment.find(params[:id])
respond_to do |format|
format.html
format.json { render :json => #post }
end
end
def edit
#comment = Comment.find(params[:id])
end
comments\show.html.erb
<p>
<b>Commenter:</b>
<%= #comment.user_id %>
</p>
<p>
<b>Comment:</b>
<%= #comment.text %>
</p>
<%= link_to 'View Comment', comment_path(?) %> |
<%= link_to 'Edit Comment', edit_comment_path(?) %> |
<%= link_to 'Delete Comment', [#post, comment],
:confirm => 'Are you sure?',
:method => :delete %></p>
Are you seeing:
Routing Error
No route matches {:action=>"show", :controller=>"comments"}
Try running rake routes for more information on available routes.
I duplicated your project with the code you provided and only received that routing error because there wasn't an id being passed to the route helper methods. Because these are restful routes, the format for View Comment should be /comments/:id(.:format).
I was able to resolve this error by passing an id or comment object to the comment_path and edit_comment_path helper methods like so:
<%= link_to 'View Comment', comment_path(2) %> |
<%= link_to 'Edit Comment', edit_comment_path(3) %> |
<%= link_to 'Delete Comment', [#post, comment],
:confirm => 'Are you sure?',
:method => :delete %></p>
Obviously you would want to populate them with the correct ids or comment objects rather than just some random id.
Hope this helps.
Cheers!
Related
Controller:
def index
#assets = current_customer.assets
end
def destroy
#asset = current_customer.assets.find_by(id: params[:id])
redirect_to root_url
end
Index.html.erb:
<% for asset in #assets %>
<% assetcount += 1 %>
<%= image_tag asset.file_name.url(:thumb).to_s %>
<ul id="hover<%= assetcount %>" class="assets-dropdown text-center" data-dropdown-content>
<li>Source Image</li>
<li><%= link_to "Delete Image", asset, method: :delete %></li>
</ul>
<% end %>
Routes:
resources :customers do
resources :assets
end
When I click on my Delete Image link_to I get a Routing Error: No route matches [DELETE] "/"
My routes:
home_index_path GET /home/index(.:format) home#index
root_path GET / home#index
customer_assets_path GET /customers/:customer_id/assets(.:format) assets#index
POST /customers/:customer_id/assets(.:format) assets#create
new_customer_asset_path GET /customers/:customer_id/assets/new(.:format) assets#new
edit_customer_asset_path GET /customers/:customer_id/assets/:id/edit(.:format) assets#edit
customer_asset_path GET /customers/:customer_id/assets/:id(.:format) assets#show
PATCH /customers/:customer_id/assets/:id(.:format) assets#update
PUT /customers/:customer_id/assets/:id(.:format) assets#update
DELETE /customers/:customer_id/assets/:id(.:format) assets#destroy
customers_path GET /customers(.:format) customers#index
POST /customers(.:format) customers#create
new_customer_path GET /customers/new(.:format) customers#new
edit_customer_path GET /customers/:id/edit(.:format) customers#edit
customer_path GET /customers/:id(.:format) customers#show
PATCH /customers/:id(.:format) customers#update
PUT /customers/:id(.:format) customers#update
DELETE /customers/:id(.:format) customers#destroy
sessions_path POST /sessions(.:format) sessions#create
new_session_path GET /sessions/new(.:format) sessions#new
session_path DELETE /sessions/:id(.:format) sessions#destroy
register_path GET /register(.:format) customers#new
signout_path DELETE /signout(.:format) sessions#destroy
signin_path GET /signin(.:format) sessions#new
It looks like the route is there.. DELETE /customers/:customer_id/assets/:id(.:format) assets#destroy
Anyone know why?
Your error is in this line
<%= link_to "Delete Image", asset, method: :delete %>
You want to pass the customer as well
<%= link_to "Delete Image", [current_customer, asset], method: :delete %></li>
To be more clear you might want
<%= link_to "Delete Image", path_for(current_customer, asset), method: :delete %></li>
Also, you are not actually destroying the #asset in your destroy method :)
def destroy
if asset = current_customer.assets.find_by(id: params[:id])
asset.destroy! #or destroy without ! but then it could rollback in not destroy
end
redirect_to root_url
end
<%= link_to "Delete Image", [current_customer, asset], method: :delete %>
If 'current_customer' is a helper and it is available in the view:
<%= link_to "Delete Image", [current_customer, asset], method: :delete %>
If not:
<%= link_to "Delete Image", [asset.customer, asset], method: :delete %>
You can also change your routes if you want assets not to be nested in customers when destroy:
resources :customers do
resources :assets, exept: :destroy
end
resources :assets, only: :destroy
I am learning rails by following the rails 3 guide.
The blog application have ran now,however I want to make the comment editable,and make the update ,create form both in the post show page. so I make the following modifiation:
post.show.htm.erb:
<h2>Comments</h2>
<% #post.comments.each do |comment| %>
<tr>
<td><%= comment.commenter %></td>
<td><%= comment.body %></td>
<td><%= link_to 'Edit', edit_post_comment_path(#post,comment) %></td>
<td><%= link_to 'Destroy', post_comment_path(#post,comment), confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
</table>
<h2>Add a comment:</h2>
#here,I can not set the form_for property.
<%= form_for([#post,#comment],:url=>post_comment_path) do |f| %>
<div class="field">
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The controller controller:
class CommentsController < ApplicationController
# GET /posts/1/comments/1/edit
def edit
#render json: params
#post=Post.find(params[:post_id])
#comments=Comment.all
#comment = Comment.find(params[:id])
render "/posts/show"
end
#other action omitted
def show
# I donot know what to do here
end
end
However I can not access the link:
http://localhost:3000/posts/1
I get the error:
No route matches {:action=>"show", :controller=>"comments"}
In fact,as you can see I have the show action in CommentController.
And,I wonder why it will access the comments#show action?
This is my routes:
post_comments GET /posts/:post_id/comments(.:format) comments#index
POST /posts/:post_id/comments(.:format) comments#create
new_post_comment GET /posts/:post_id/comments/new(.:format) comments#new
edit_post_comment GET /posts/:post_id/comments/:id/edit(.:format) comments#edit
post_comment GET /posts/:post_id/comments/:id(.:format) comments#show
PUT /posts/:post_id/comments/:id(.:format) comments#update
DELETE /posts/:post_id/comments/:id(.:format) comments#destroy
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
home_index GET /home/index(.:format) home#index
root / home#index
The /posts/:id will trigger posts#show. why comments#show?
if u need to edit the post, then add
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post.update_attributes(params[:post])
redirect_to some_path and return
end
render 'edit' #error
end
the form for edit should send a PUT request to the server. rails maps the url and the request ( like GET/POST/PUT/DELETE) using the routes file to the controller actions.
here
PUT /posts/:id(.:format) posts#update
the request is PUT, controller is PostsController and the action is update.
also,
post GET /posts/:id(.:format) posts#show
u need to pass the http request from the form if its POST/PUT/DELETE.
u can do so for 'edit'
<%= form_for([#post,#comment],:url=>post_comment_path, :method => :put) do |f| %>
maps to the show request for PostsController. the format is html bydefault. for more info, have a detailed look at the server log.
coachings GET /coachings(.:format) {:action=>"index", :controller=>"coachings"}
POST /coachings(.:format) {:action=>"create", :controller=>"coachings"}
new_coaching GET /coachings/new(.:format) {:action=>"new", :controller=>"coachings"}
edit_coaching GET /coachings/:id/edit(.:format) {:action=>"edit", :controller=>"coachings"}
coaching GET /coachings/:id(.:format) {:action=>"show", :controller=>"coachings"}
PUT /coachings/:id(.:format) {:action=>"update", :controller=>"coachings"}
DELETE /coachings/:id(.:format) {:action=>"destroy", :controller=>"coachings"}
my routes are correct, here is my view index
<%= link_to 'Destroy', coaching, :confirm 'Are you sure?', :method => :destroy %>
here is my controller
def destroy
#coaching = Coaching.find(params[:id])
#coaching.destroy
respond_to do |format|
format.html { redirect_to coachings_path }
format.json { head :ok }
end
end
any ideas why i get this error? i'm new to RoR this is my first projects i've done by myself.
Use :delete method
<%= link_to 'Destroy', coaching, :confirm => 'Are you sure?', :method => :delete %>
In your link_to you are using a method of destroy which isn't a valid HTTP verb so Rails is probably defaulting to POST. You'll need to use DELETE instead:
<%= link_to 'Destroy', coaching, confirm: 'Are you sure?', method: :delete %>
I got it!
= link_to 'Zurück', page_path
That doesn't work in a new page. The page hasn't yet been created, so I can not go back to it...
This sure works fine in "edit", where the page exists
A good reason to spend the effort to get rspec to run :-)
Anyway, thank for the comments!
I got a little further....
The routing seems to work. But my form seems to be the problem?!
This is my view/pages/new.html.haml
= render 'form'
and it gets rendered if I do this:
%p I should be a form for the new page...
=# render 'form'
So it seems to be a problem with my _form.html.haml - which works fine for "edit"
= javascript_include_tag "#{root_url}javascripts/tiny_mce_head.js"
= form_for #page do |f|
-if #page.errors.any?
#error_explanation
%h2= "#{pluralize(#page.errors.count, "error")} prohibited this page from being saved:"
%ul
- #page.errors.full_messages.each do |msg|
%li= msg
.field
= f.text_area( :content, :class => 'mce_editor')
.field
= f.label :fan_only
= f.check_box :fan_only
.field
= f.label :short_name
%br
= f.text_field :short_name
.field
= f.label :title
%br
= f.text_field :title
.actions
= f.submit 'Save'
= link_to 'Zurück', page_path
Any ideas???
I've already tried without the javascript_include_tag
original post
I can't create a new page anymore. It was working and I have no idea why it doesn't anymore!
If I browse to http://localhost:3000/pages/new
I get the following message:
No route matches {:action=>"show", :controller=>"pages"}
These are my routes
scope '/my-scope' do
resources :pages do
resources :articles
end
end
root :to => 'pages#index'
rake routes
page_articles GET /my-scope/pages/:page_id/articles(.:format) {:action=>"index", :controller=>"articles"}
POST /my-scope/pages/:page_id/articles(.:format) {:action=>"create", :controller=>"articles"}
new_page_article GET /my-scope/pages/:page_id/articles/new(.:format) {:action=>"new", :controller=>"articles"}
edit_page_article GET /my-scope/pages/:page_id/articles/:id/edit(.:format) {:action=>"edit", :controller=>"articles"}
page_article GET /my-scope/pages/:page_id/articles/:id(.:format) {:action=>"show", :controller=>"articles"}
PUT /my-scope/pages/:page_id/articles/:id(.:format) {:action=>"update", :controller=>"articles"}
DELETE /my-scope/pages/:page_id/articles/:id(.:format) {:action=>"destroy", :controller=>"articles"}
pages GET /my-scope/pages(.:format) {:action=>"index", :controller=>"pages"}
POST /my-scope/pages(.:format) {:action=>"create", :controller=>"pages"}
new_page GET /my-scope/pages/new(.:format) {:action=>"new", :controller=>"pages"}
edit_page GET /my-scope/pages/:id/edit(.:format) {:action=>"edit", :controller=>"pages"}
page GET /my-scope/pages/:id(.:format) {:action=>"show", :controller=>"pages"}
PUT /my-scope/pages/:id(.:format) {:action=>"update", :controller=>"pages"}
DELETE /my-scope/pages/:id(.:format) {:action=>"destroy", :controller=>"pages"}
root / {:controller=>"pages", :action=>"index"}
controllers/pages_controller.rb methodes show and new
# GET /pages/1
# GET /pages/1.json
def show
#page = Page.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #page }
end
end
# GET /pages/new
# GET /pages/new.json
def new
#page = Page.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #page }
end
end
This is my view/pages.html.haml
%p#notice= notice
%content.viewmode
= raw parse_content #page.content
-#if admin?
= link_to 'Edit page', edit_page_path(#page)
= link_to 'New page', new_page_path
= link_to 'Destroy page', #page, :confirm => 'Are you sure to delete page #{#page.title}?', :method => :delete
= link_to 'New article', new_page_article_path(#page)
-if #page.articles.empty?
/
= "No articles for page #{#page.short_name}"
- else
%ul.article_list
= show_articles
I'd be glad if anyone could just give me a few ideas where to start searching.
I tried but I don't get any further.
You're using scopes, so your url should be http://localhost:3000/my-scope/pages/new
I am in the process of still learning Rails 3 but routes are driving me crazy. I am trying to use a namespace to separate an administration section of the site. Problem is that some things in the namespace simply don't work and also route to the wrong place. For example using rails generated routes by specifying a resource the view points to the wrong route when passed an object so the edit form won't work.
Links with link_to don't work either even when the route does exist it says it doesn't. Firstly here is the namespaced routes output from rake routes.
namespace :admin do
resources :users
end
admin_users GET /admin/users(.:format) {:action=>"index", :controller=>"admin/users"}
POST /admin/users(.:format) {:action=>"create", :controller=>"admin/users"}
new_admin_user GET /admin/users/new(.:format) {:action=>"new", :controller=>"admin/users"}
edit_admin_user GET /admin/users/:id/edit(.:format) {:action=>"edit", :controller=>"admin/users"}
admin_user PUT /admin/users/:id(.:format) {:action=>"update", :controller=>"admin/users"}
DELETE /admin/users/:id(.:format) {:action=>"destroy", :controller=>"admin/users"}
Controller:
class Admin::UsersController < ApplicationController
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def edit
#user = User.find(params[:id])
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to(#user, :notice => 'User was successfully created.')
else
render :action => "new"
end
end
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
redirect_to(admin_users_path, :notice => 'User was successfully updated.')
else
render :action => "edit"
end
end
def destroy
#user = User.find(params[:id])
#user.destroy
redirect_to(admin_users_path)
end
end
Example view: index.html.erb listing all users
<h1>Listing users</h1>
<table>
<% for user in #users %>
<tr>
<td><%= user.id %></td>
<td><%= user.username %></td>
<td><%= user.email %></td>
<td><%= link_to 'Show', #user %></td>
<td><%= link_to 'Edit', edit_admin_user_path(user) %></td>
<td><%= link_to 'Destroy', admin_user_path, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New User', new_admin_user_path %>
Using the edit view is also having a problem. The edit form should point to the update route but does not. Instead it points to the edit route (basically itself) when only being passed a User object. From what I have been reading using an object in forms is the recommended way but this cant be a good thing if it does not work.
I get this error on listing all users page.
No route matches {:action=>"update", :controller=>"admin/users"}
Extracted source (around line #17):
17: <td><%= link_to 'Destroy', admin_user_path, :confirm => 'Are you sure?', :method => :delete %></td>
I am so trying to persevere but this is driving me loopy. FYI: Yes I know there are authentication frameworks out there but I am trying to make one from scratch. This is a learning experience and as such just using gems and plugins willy nilly is not the way to go in my opinion.
Thank you
Onyth
You're missing the id in the delete link
Try with
<td><%= link_to 'Destroy', admin_user_path(user), :confirm => 'Are you sure?', :method => :delete %></td>
(changed admin_user_path to admin_user_path(user) as the link)
If you do a rake routes you would see something like this:
admin_users GET /admin/users(.:format) {:controller=>"admin/users", :action=>"index"}
POST /admin/users(.:format) {:controller=>"admin/users", :action=>"create"}
new_admin_user GET /admin/users/new(.:format) {:controller=>"admin/users", :action=>"new"}
edit_admin_user GET /admin/users/:id/edit(.:format) {:controller=>"admin/users", :action=>"edit"}
admin_user GET /admin/users/:id(.:format) {:controller=>"admin/users", :action=>"show"}
PUT /admin/users/:id(.:format) {:controller=>"admin/users", :action=>"update"}
DELETE /admin/users/:id(.:format) {:controller=>"admin/users", :action=>"destroy"}
admin_pages GET /admin/pages(.:format) {:controller=>"admin/pages", :action=>"index"}
POST /admin/pages(.:format) {:controller=>"admin/pages", :action=>"create"}
new_admin_page GET /admin/pages/new(.:format) {:controller=>"admin/pages", :action=>"new"}
edit_admin_page GET /admin/pages/:id/edit(.:format) {:controller=>"admin/pages", :action=>"edit"}
admin_page GET /admin/pages/:id(.:format) {:controller=>"admin/pages", :action=>"show"}
PUT /admin/pages/:id(.:format) {:controller=>"admin/pages", :action=>"update"}
DELETE /admin/pages/:id(.:format) {:controller=>"admin/pages", :action=>"destroy"}
So you can derive
admin_user_path
which would be the same as
user_path
Then you would pass the #user in admin_user_path like so:
admin_user_path(#user)
The :method should then call the destroy method instead of going to the show method automatically! :)
To get the form_for working, I found the following resource: http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for
Under the form_for section, they explain namespace routing with form_for as:
For namespaced routes, like admin_post_url:
<%= form_for([:admin, #post]) do |f| %>
...
<% end %>
For information regarding rake routes check out: http://guides.rubyonrails.org/command_line.html#rake-is-ruby-make then under section 2.4.9 Miscellaneous Tasks they explain rake --tasks shows you various rake commands that you can use and rake routes shows you route paths available.
Hope this helps!