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?
Related
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!
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.
Alright total noob, tried to find out what was happening but I haven't seen this come up with anyone else as far as I could find.
I'm going through a very basic blog tutorial with rails for the second time. made the home controller and the index view for it. all good. Next i made the 'posts' controller with basic classes and then views for index, edit, new, and show.
class PostsController < ApplicationController
def index
end
def new
end
def create
end
def edit
end
def update
end
def show
end
def destroy
end
end
The html for the views in their respective files
<h1>New Posts</h1>
<h1>Edit Posts</h1>
<h1>Show Posts</h1>
PROBLEM: In the browser when I go to localhost:3000/posts/edit it displays "Show Posts" instead of "Edit Posts". /show also displays "Show Posts". /new works fine and displays "New Posts".
I checked and it looks like localhost:3000/posts/literallyanything will display "Show posts".
I know this is potato level but I thought it was really odd and can't figure out why that would happen
Assuming you have a resource route for posts defined in your routing file like this:
resources :posts
you need to hit
localhost:3000/posts/<post id>/edit
More docs on routing here:
http://guides.rubyonrails.org/routing.html
You can always run rake:routes from your terminal to find out what route you need to hit for any given controller action.
I have this form in my application.html.erb.
<%= form_tag(:action=>"index", :controller=>"posts") %>
<p>
// code here
</p>
I dont understand why is this getting directed to posts->create instead of posts->index?
Thanks.
Basically, Rails observes and obeys "RESTful" web service architecture. With REST and Rails, there are seven different ways to interact with a server regarding a resource. With your current code, specifying the form's action as index doesn't make sense: Rails' form helpers can either POST, PUT or DELETE.
If you wanted to create a post, then redirect to the index, you can do so in the applicable controller action:
class PostsController < ApplicationController
...
def create
#post = Post.new
respond_to do |format|
if #post.save
format.html { redirect_to(:action => 'index') }
end
end
While your form would look like:
<% form_for #post do |f| %>
# put whatever fields necessary to create the post here
<% end %>
You seem to be a little mixed up with respect to the uses for each action. Here's a quick summary of typical RESTful usage:
Index -> view a list of items
New/Edit -> form where items are added or edited
Create/update -> controller action where items are created/updated
The reason your routes file is not taking you to index is because index is not an action where posts are typically created or updated. The best way is to go RESTful. Unless you have a very unusual situation, the best way to set your system up is probably a little like this:
# routes.rb
resources :posts
# application.html.erb (or better: posts/_form.html.erb).
<% form_for #post do |f| %>
<% end %>
# posts controller, whichever action you want to use
def new
#post = Post.new
end
By putting the form in a partial called form you can access it in new, edit, or wherever else you need to manipulate a post in your system.
I have this structure for the table course:
Search page -> Result Page -> Edit Page -> Show page
When i go from result page to a specific course edit page, i edit it, and end up on the show page, but when i hit back, i get a loop from show to edit, and back to show and so on.
I want the edit page to back to the result page if it came from there.
im using this on both:
<%= link_to "Back", :back %>
When you actually update your record having edited it you're likely to be doing a redirect from an update action via a put request to show. Even if you're not, and if you're defying convention and updating from the show action, you're trying to navigate to a post action with a get request. If I understand you correctly, you want to be able to edit from either the search result or the show page. What you should do is define a method that allows you to store a location in the session on demand. Put it in the application controller and it will be available to all of your controllers.
# copy this into your application_controller.rb file :
private
def store_location
session[:return_to] = request.request_uri
end
#copy this to the top of your item_controller.rb file:
before_filter :store_location, :only => [:search, :show]
#replace your <%= link_to "Back", :back %> with
<%= link_to 'back', session[:return_to] -%>