Actions for Deleting Model Records
In this demonstration, I will show how to add controller actions and views that allow users to delete database records. We will continue to build upon the QuizMe project from the previous demos.
Now that the QuizMe app has features to create (new
/create
), read (index
/show
), and update (edit
/update
) multiple-choice questions—the C, the R, and the U in CRUD—the last thing to do is add the functionality for deleting questions. Unlike the new
/create
and edit
/update
features, deleting records will not involve a form. Instead, we will implement a destroy
controller action that deletes a specified McQuestion
record, and to access the action, we will add a 🗑 (trash can) link to each question on the index
and the show
pages, as depicted in Figure 1.
Once the destroy
action has deleted the record, it will redirect the browser to the index
page, displaying a flash success notification, as depicted in Figure 2.
Implementing this destroy
functionality will involve two main parts:
- We will first implement the
destroy
route andMcQuestionsController
action, making the web app receptive to HTTP DELETE requests to deleteMcQuestion
records. - We will add to the
McQuestion
model class’index
andshow
pages special hyperlinks that send HTTP DELETE requests, so users can delete records by clicking the links.
1. Deleting McQuestion
Records with a destroy
Controller Action
As a first step, add to routes.rb
the standard resource route for the destroy
action, inserting it after the update
routes, like this:
delete 'mc_questions/:id', to: 'mc_questions#destroy' # destroy
Note that this delete
route uses a URI pattern that contains an id
(similar to the show
and update
routes). That id
will indicate the question to be deleted from the database.
Next, add to the McQuestionsController
class a code skeleton with pseudocode comments for the destroy
controller action, like this:
def destroy
# load existing object again from URL param
# destroy object
# respond_to block
# success message
# redirect to index
end
We’ll fill in the code for this method bit by bit. When finished, it will (1) first retrieve the object to be deleted based on the id
in the request URL, (2) then delete the object, (3) then set a flash notification, and (4) finally respond with an HTTP redirect to the index
page.
Add code to retrieve the object to be deleted using the id
from the path in params
hash, and then delete it using the model’s destroy
method, like this:
# load existing object again from URL param
question = McQuestion.find(params[:id])
# destroy object
question.destroy
Complete the logic for the respond_to
block by adding a success message to the flash
has and an HTTP redirect to the index
page, like this:
# respond_to block
respond_to do |format|
format.html do
# success message
flash[:success] = 'Question removed successfully'
# redirect to index
redirect_to mc_questions_url
end
end
The web app should now be receptive to HTTP DELETE requests that delete specified multiple-choice questions from the database; however, we do not yet have a good way to test this functionality. For example, DELETE requests cannot be sent in the same way we send GET requests, by entering a URL into the browser’s location bar. In the next part, we will add links to our existing pages to enable sending such HTTP DELETE requests.
2. Linking to the destroy
action from the index
and show
Pages for McQuestion
Records
Add to the index
view a 🗑 (trash can) link to the destroy
action for each question, like this:
<p>
<%= question.question %>
<%= link_to '🔎', mc_question_path(question) %>
<%= link_to '🖋', edit_mc_question_path(question) %>
<%= link_to '🗑', mc_question_path(question), method: :delete %>
</p>
Note that in this call to the link_to
method we use a method
option with the value :delete
to make it so that clicking the link produces an HTTP DELETE request (instead of the usual GET request).
Similar to the index
view, add to the show
view a 🗑 link ot the destroy
action, like this:
<p>
<%= question.question %>
<%= link_to '🖋', edit_mc_question_path(question) %>
<%= link_to '🗑', mc_question_path(question), method: :delete %>
</p>
Verify that the destroy
hyperlinks work now by running the app and testing out the links on the index
and show
pages.
The QuizMe app now offers full CRUD functionality by providing the standard Rails resource routes, actions, and views. In the upcoming demos, we will see how to use RESTful resources when the database design becomes more complex (e.g., by adding model class associations/foreign keys).