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
Related
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)
I'm pretty much an amateur when it comes to Rails. I got this to work, however I feel like the code is not efficient enough.
Is there any way to speed this up? And also it this how a professional would do it?
Controller
def mark_read
#topic = Topic.find(params[:id])
#topic.mark_as_read! :for => current_user
redirect_to user_path(current_user.slug)
end
def mark_all_read
Topic.mark_as_read! :all, :for => current_user
redirect_to user_path(current_user.slug)
end
Routes
resources :users do
member do
post :mark_read
post :mark_all_read
end
end
View
<% if current_user.id == #user.id %>
<%= link_to "Mark all as read", mark_all_read_user_path, :method=> :post %>
<h4> List of posts unread by you </h4>
<% #unread.each do |topic| %>
<% if #user.following?(Product.find(topic.product_id)) %>
<li> <%= topic.title %> <%= link_to "Mark as read", mark_read_user_path(topic), :method=> :post %> </li>
<% end %>
<% end %>
Is there someway that I could call an action in the controller without a route? I feel it would make the workflow neater.
The answer to your question is no. You can not have access any action in the controller unless it has a route, or its a CRUD generated by default, for example:
resources :articles
generates
Controller#Action
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
I am encountering a routing error when I try to render a partial in an ajax call:
Routing Error
No route matches {:action=>"destroy", :controller=>"relationships", :user_id=>#<User id: 2, username: .....
Within my app, I have a list of followers for a user displayed on the profile page. Instead of paginating the followers, I would like to try to return the next offset of followers from the server through AJAX. My view already utilizes partials for displaying a list of these followers (limited to 5 records).
My goal is to use an AJAX call to return this partial with the next offset of records formated (I haven't implemented the functionality to return offset records yet - I'm just trying to get the ajax working first). The partials work fine when I visit the profile page in my browser (and view the first 5 records), the error occurs when I make the AJAX call.
Here is the form in the view where the ajax call originates:
<%= form_tag user_relationships_path(#user), method: :get, remote: true do %>
<%= submit_tag 'load more...' %>
<% end %>
Here is the route:
resources :users, only: [:index, :show, :new, :create, :edit, :update, :destroy] do
resources :relationships, only: [:create, :destroy, :index]
end
Here is my controller action (relationships#index) which responds to the request:
def index
#user = User.find_by_username(params[:user_id])
respond_to do |format|
format.js { render 'load_followers' }
end
end
The load_followers.js.erb partial:
$('ul#followers').append("<%= render 'users/following_items', users: #user.followers %>")
The users/following_items.html.erb partial:
<% users.each do |user| %>
<li class="clearfix">
<div class="box-gravatar pull-left">
<%= link_to user do %>
<%= gravatar_for user, 40 %>
<% end %>
</div>
<div class="pull-right">
<%= render 'relationships/follow', user: user %>
</div>
<%= link_to user.username, user %>
<div class="box-author">joined <%= join_date_for user %></div>
</li>
<% end %>
And finally the relationships/follow.html.erb partial:
<% unless current_user?(user) %>
<% if current_user.following? user %>
<p><%= link_to 'unfollow', user_relationship_path(user), method: :delete, class: "btn" %></p>
<% else %>
<p><%= link_to 'follow', user_relationships_path(user), method: :post, class: "btn btn-primary" %></p>
<% end %>
<% end %>
I have tracked down the offending code to the relationships/follow.html.erb partial. When that is removed, the ajax call works fine and the partial is appended to the end of the ul. Clearly it has to do with rails having an issue with the link_to to the relationships#destroy method - however, nothing I've tried seems to work.
Edit: Here are the results of running rake routes:
root / posts#index
posts_test /posts/test(.:format) posts#test
submit /submit(.:format) posts#new
signup /signup(.:format) users#new
login /login(.:format) sessions#new
logout DELETE /logout(.:format) sessions#destroy
about /about(.:format) about#index
search /search(.:format) search#index
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
post_comments POST /posts/:post_id/comments(.:format) comments#create
post_votes POST /posts/:post_id/votes(.:format) votes#create
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
post GET /posts/:id(.:format) posts#show
user_relationships GET /users/:user_id/relationships(.:format) relationships#index
POST /users/:user_id/relationships(.:format) relationships#create
new_user_relationship GET /users/:user_id/relationships/new(.:format) relationships#new
edit_user_relationship GET /users/:user_id/relationships/:id/edit(.:format) relationships#edit
user_relationship GET /users/:user_id/relationships/:id(.:format) relationships#show
PUT /users/:user_id/relationships/:id(.:format) relationships#update
DELETE /users/:user_id/relationships/:id(.:format) relationships#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
categories GET /categories(.:format) categories#index
POST /categories(.:format) categories#create
new_category GET /categories/new(.:format) categories#new
category GET /categories/:id(.:format) categories#show
/:category(.:format) posts#index
Thanks!
Notices your rake routes outputted this line:
DELETE /users/:user_id/relationships/:id(.:format)
This means your named route user_relationship is expecting both user and relationship IDs. Reason being, relationship is a nested resource of user.
So for instance you currently have this in your link to:
= link_to 'unfollow', user_relationship_path(user), method: :delete, class: "btn"
Instead it should be something like:
= link_to 'unfollow', user_relationship_path(user, relationship), method: :delete, class: "btn"
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!
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!