Destroy method not working (routing question)


#1

Hi all,

I’m trying to implement an admin control panel for my application and
everything seems to work fine, except when I try to call the destroy
method from the view. I really tried to search for a solution, reading
some routing rails articles, but can’t figure out what’s going on.
When I call the method from the console it works. Calling it from the
view redirects to the list action, but the product is not deleted.

View:

<% for product in @products %>
<%= link_to ‘delete’, [:admin, product],:confirm => ‘Are you
sure?’,:method => :delete %>
<% end %>

My routes.rb:

map.namespace :admin do |admin|
admin.resources :categories
admin.resources :subcategories
admin.resources :products
end

Controller:

def destroy
@product = Product.find(params[:id])
@product.destroy
respond_to do |format|
format.html { redirect_to(products_url) }
end
end

Thanks for your help,


Alberto


#2

Hello Alberto,

In your view, what are you trying to say with [:admin, product].
Is it perhaps {:controller => “admin/product”}?

rake routes on your routes.rb shows:

DELETE /admin/products/:id
{:action=>“destroy”, :controller=>“admin/products”}

So you should be able to use:

<%= link_to ‘delete’, products_path(product), :method => :delete,
:confirm => ‘Are you sure?’ %>

Rick


#3

This might actually work :slight_smile:

<%= link_to ‘delete’, admin_products_path(product),
:method => :delete, :confirm => ‘Are you sure?’ %>

Rick


#4

Hello Rick,

Thanks for you reply. Yes, the controller is “admin/products”. With
rake routes I have:

DELETE /admin/products/:id {:controller=>“admin/
products”, :action=>“destroy”}

I tried to call admin_products_path(product) like you suggested but it
shows me an error (You have a nil object …). Calling
admin_product_path works but don’t delete the product, it redirects to
the list action and the product remains there. Rails version is 2.1.1.
When I told you that I called the destroy method using the console,
what I did was execute “Product.find(3).destroy”. Is there another way
to test a controller’s method using the console ?


Alberto


#5

Hello again,

So let’s back up one step. Your error is “You have a nil object…”,
let’s prove that is true.

How about changing the
<%= link_to … %>
to something simple like

Product ID: <%= product %>

Then, when that gives you nil cut the loop out and insert a statement
that displays something meaningful from @products. If that produces a
nil that you have to look at how you got here (in the view) and what
was your assumption how @products got to have a value associated with
it.

This would be easier for you if you single stepped through a
debugger. You might consider it time well spent to learn how.

Rick


#6

Hi alberto!

I don’t think your syntax is the problem here, [:admin, product] or
admin_product_path should work fine.
I’m afraid I can’t work out what’s going wrong but why not try adding
“logger.info(‘message here’ )” to your controller both before and
after the destroy call.

You can then check your log and find out what code is being run and
what isn’t. Also, do you have anything in your model that may be
causing an issue, a :before_destroy perhaps?

Gavin


#7

OK Rick, I did what you said and confirmed that @products is
populated. That error only occurs when I use “admin_products_path”. If
I change it to “admin_product_path” no error occurs but the product isn
´t deleted.
I will follow your hint later and try to debug the application to see
what is going wrong. I’ll post the results.

Thank you,


Alberto


#8

The link should be:

<%= link_to “Delete”, admin_product_path(product), :method
=> :delete, :confirm => “Are you sure you want to delete this
product?” %>

Just to clarify: the controller you mean is admin/
products_controller.rb, right?


#9

OK, first I tried to call logger.info ‘message’ but nothing was logged
(development.log). After this I installed ruby-debug and put an
“debugger”
instruction but the execution didn’t stopped on that point. So I really
believe that the destroy method isn’t being called, but why?I know that
is
something really stupid but can’t see what’s wrong …
Ryan, the controller is ‘admin/products_controller.rb’.
I will try to fix it using the link Rick suggested.

Thanks,


Alberto


#10

Hey Alberto,

Take a look at this site, I think it’s pretty close match to what you
are trying to accomplish:

http://icebergist.com/posts/restful-admin-namespaced-controller-using-scaffolding

Rick


#11

What else is in your controller? Anything in application.rb?

Ryan B.
Freelancer
http://frozenplague.net


#12

Ryan,

Nothing in application.rb. I migrated this app from rails 1.2 and now
I want to create an admin control panel.

admin/products_controller.rb:

class Admin::ProductsController < ApplicationController

layout ‘admin’

def index
list
render :action => ‘list’
end

GETs should be safe (see

http://www.w3.org/2001/tag/doc/whenToUseGet.html)
verify :method => :post, :only => [ :destroy, :create, :update ],
:redirect_to => { :action => :index }

def list
@products = Product.paginate(:per_page => 8, :page => params
[:page])
end

def new
@product = Product.new
end

def create
@product = Product.new(params[:product])
if @product.save
redirect_to admin_products_path
else
render :action => ‘new’
end
end

def edit
@product = Product.find(params[:id])
end

def update
@product = Product.find(params[:id])
if @product.update_attributes(params[:product])
redirect_to admin_products_path
else
render :action => ‘edit’
end
end

def destroy
@product = Product.find(params[:id])
@product.destroy
end

end


Alberto


#13

What’s in your routes.rb file?

2008/11/25 cardinallijr removed_email_address@domain.invalid

    :redirect_to => { :action => :index }

def create
end
def destroy

What else is in your controller? Anything in application.rb?

called, but why?
wrote:


Appreciated my help?
Recommend me on Working With Rails
http://workingwithrails.com/person/11030-ryan-bigg


#14

routes.rb

map.namespace :admin do |admin|
admin.resources :categories
admin.resources :subcategories
admin.resources :products
end


Alberto

On Nov 25, 12:15 am, “Ryan B. (Radar)” removed_email_address@domain.invalid


#15

Rick,

You are right. I tried to do what you suggested with a new project and
it really worked. But with my project it doesn´t work. Something is
wrong with my project, I´ll try to discover later. Maybe something
with pagination or the model, I don´t know. If I discover something I
´ll post the results later.

Thanks for your help,


Alberto


#16

Hey Alberto,

Here’s what’s in my

config/route.rb:

map.namespace :admin do |admin|
admin.resources :products
end

app/views/admin/products/index.html.erb

<% for product in @products %>

<%=h product.name %> <%= link_to 'Show', [:admin,product] %> <%= link_to 'Edit', edit_admin_product_path(product) %> <%= link_to 'Destroy', [:admin,product], :confirm => 'Are you sure?', :method => :delete %> <% end %> =========

app/controllers/admin/products_controller.rb

def destroy
@product = Product.find(params[:id])
@product.destroy

respond_to do |format|
  format.html { redirect_to admin_products_path }
  format.xml  { head :ok }
end

end

And it works - check out this site:

http://icebergist.com/posts/restful-admin-namespaced-controller-using-scaffolding

Rick


#17

OK, removed the “# GETs should be safe” part of the controller and it
worked.

GETs should be safe (see

http://www.w3.org/2001/tag/doc/whenToUseGet.html)
verify :method => :post, :only => [ :destroy, :create, :update ],
:redirect_to => { :action => :index }

Does it really needs to be inserted inside the controller ?


Alberto