Why ruby destroy method is not destroying? (see below) - ruby-on-rails

My controller
def destroy
#article = Article.find(params[:id])
#article.destroy
redirect_to articles_path
end
my view
<td><%= link_to 'Destroy', article_path(article),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
Notes from Tutorial Page:
Here we're using link_to in a different way. We pass the named route as the second argument, and then the options as another argument. The :method and 'data-confirm' options are used as HTML5 attributes so that when the link is clicked, Rails will first show a confirm dialog to the user, and then submit the link with method delete.
Whenever I click the delete button, it shows the edit result
strong text

One thing you could do to get a more useful exception would be to add a bang ! to your destroy method, which will raise an exception if the destroy fails.
It's possible that there is some failing association validation or callback that is raising an exception that you're not seeing. Try using this for your destroy method and watching your server logs after you click the link:
def destroy
#article = Article.find(params[:id])
#article.destroy!
redirect_to articles_path
end
If you're not seeing anything in your server log, it may be a routing issue

Your controller code of destroy action as well as view code of delete link seems fine, then in order to exactly dig the reason why it's not working do one thing, just open console and try to manually destroy an article with bang as NM Pennypacker suggested above.
Article.find(1).destroy!

Initially I got confused little (As I am using lower version of rails), later found and read this article
This will clear your idea about other methods also along with destroy!

Related

Destroy user - with custom authentication (rails)

Quick question: I was following this tutorial where they built user authentication system instead of using devise.
My issue is the tutorial misses the destroy action in which devise has ready and does so well.
My create action is
User_controller.rb
def create
#user = User.create(user_params)
session[:user_id] = #user.id
if #user.valid?
flash[:notice] = "You've successfully Created Your Account! Welcome!"
redirect_to root_path
else
flash[:notice] = "Opps Something went bad, :/ Try again please"
render action: 'new'
end
end
I really hope this is not a total nuub question event though I am one. But can somebody offer some tips for a destroy action ? and also how would that action appear in routes and through a link_to method. I want to create a deactivate page that gives a send off and the user is able to cancel their account. Any cool tips toward the deactivate page on the side will be much appreciated.
The Hartl rails tutorial covers this quite well IMO. Once you have the destroy action defined in your controller, you could create a link to deactivate their account calling the destroy action and redirect to the home page, or a goodbye page. As long as users is listed as a resource in your routes, you shouldn't need to modify your routes as DELETE is a standard CRUD command.
https://www.railstutorial.org/book/updating_and_deleting_users
for example:
user_controller
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_url
end
view
<%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?" } %>
For the deactivate page, maybe you can add a boolean column in your users table, say is_active,
and another controller action for deactivation, say deactivate, which will just set the is_active column as false for that user.
see sample routes.rb for the route.
#ncarroll 's sample is correct, for the routes, if you have in your routes.rb:
Rails.application.routes.draw do
resources :users do
put :deactivate
end
end
This will automatically create routes for the RESTful actions, which includes destroy.

destroy controller routing to show view (rails 4.1.8)

Been struggling through the rails guide build a blog tutorial. Have, I think, everything working aside from the destroy link on the index page. When clicked, it routes to the show view for that article that's clicked on to be deleted. this is from the index.html.erb. any help is greatly appreciated.
def destroy
#article = Article.find(params[:id])
#article.destroy
redirect_to articles_path
end
private
def article_params
params.require(:article).permit(:title, :text)
end
Code:
<%= link_to 'Destroy', articles_path(#article), method: :delete %>
The reason why the method option is required is because a browser cannot send a DELETE command necessary to perform the action. Providing the option sets an extra attribute and lets rails know the action you are about to perform should be routed to the deletion route instead of a simple show
Have a look at:
Are the PUT, DELETE, HEAD, etc methods available in most web browsers?

ActionView::MissingTemplate during testing

I'm testing a rails controller and attempting to perform a get with the code:
delete :remove_logs, :id => 3
And it consistently returns me an ActionView::MissingTemplate exception. I know that this is because there is no view associated with the get. There is a route for this method (from rake routes):
remove_logs /devices/remove_logs/:id(.:format) {:controller=>"devices", :action=>"remove_logs"}
The function itself works perfectly for the actually webpage as it's being called with:
<%= link_to "Remove History", remove_logs_path(device),
:class => "medium red button", :confirm => 'This will remove all history from
this device. Are you sure?', :method => :delete %>
So my question is, is there a way to bypass or trick the test to not attempt to access the view and just access the controller method? This isn't my system I'm testing so I really don't want to make a new blank view or anything similar.
I think the problem may be related with the code in controller (remove_logs action) which usually has some code about redirecting to another url like bellow:
def destroy
#tag = Tag.find(params[:id])
#tag.destroy
redirect_to :action => :index
end
I test with Test::Unit in my rails app, and it goes fine when having redirecting code.

Form_for Gives Wrong Outputs After render :action=>'edit'

I think this question might have been asked before, but I honestly don't know how to search for it.
Basically, when I do a render :action => 'edit' in the update action in controller, somehow the view outputs the form as if it's a :action => 'new' page.
form_for gave the wrong action and f.submit gave wrong button text (it gave create instead of update)
edit:
relevant parts of controller
def edit
#user = User.find_by_email(current_user.email)
end
def update
old_password=params[:user].delete(:old_password)
#user=User.new(params[:user])
if User.find_by_email(#user.email).valid_password?(old_password)
logger.info 'Valid old password'
else
flash[:notice]='Invalid current password'
render :action=>'edit'
end
end
As discussed in the comments, #bassneck is right - while you are rendering the edit view, the form_for call looks at whether the object is persisted or not (#user.persisted?). This has the benefit in a lot of cases of being able to use one piece of form code for both new and edit views (I'll generally have a partial _form.html.erb that gets used for both situations).
In your case though, it isn't leading to the desired behaviour - so wwhat you need to do is make sure you're using the relevant user object. If you want to update a user, #user should be the object you want to update.

Rails: common approach for handling exceptions in restful actions on objects that have been destroyed?

It is very common in Rails for an objects_controller controller to have RESTful edit and destroy actions like so:
def edit
#object = Object.find(params[:id])
end
def destroy
#object = Object.find(params[:id])
#object.destroy
redirect_to :back
end
With an associated view that provides edit and destroy links like so:
<%= link_to "Edit the Object", edit_object_path(object) %>
<%= link_to "Delete", object, :confirm => 'Are you sure?', :method => :delete %>
And it is easy to blow this up. If I open two browser windows, A and B, destroy an object with the "Delete" link in browser A and then press the "Edit" link in browser B, the find() in the edit action throws an exception.
Updating to add Jakub's suggestion
There are several ways to deal with this:
catch the exception and recover gracefully in the edit action
use #object = find(:first, "conditions... etc. and test the #object in the edit action
use a general 404
But seeing as this is such a common pattern, I would love to know how other folks deal with this situation.
You edit your 404 page in public/404.html to be something reasonably friendly explaining that what the person is trying to access is not available anymore. That's the general solution. However your domain could allow for example soft-deleting and then you could offer to un-delete the record in the edit view. Checkout the Paranoid plugin for that (I'd implement it quite generally in a before_filter).

Resources