Displaying a Single Model Record
In this demonstration, I will show how to create a so-called show
page that displays one specific model record on a webpage. We will continue to build upon the QuizMe project from the previous demos.
In particular, we will add a show
page to the QuizMe app that displays a McQuestion
record stored in the database, as depicted in Figure 1.
![A web page displaying one multiple-choice question records](/rails-demos-n-deets-2020/resources/mc-question-show-page.png)
Figure 1. The show
page for a McQuestion
record.
Adding this show
page will involve several key steps:
- Adding a
show
route forMcQuestion
records that translates HTTP requests for theshow
page into invocations of the appropriate controller action. - Adding a
show
controller action to theMcQuestionsController
class created last demo that, when invoked, will retrieve the appropriateMcQuestion
record from the database and will render the appropriate view, passing in the retrieved record for the view to display. - Adding a
show
view forMcQuestion
records that will render a webpage containing whateverMcQuestion
record is passed to the view.
1. Adding a show
Route for McQuestion
Records
In routes.rb
, insert after the index
route a standard resource route for the show
action of the McQuestionsController
class, like this:
get 'mc_questions/:id', to: 'mc_questions#show', as: 'mc_question' # show
In a previous demo, we passed user data (i.e., parameters) from a webpage to the Rails server via POST requests (recall the params
hash); however, parameters can also be passed via GET requests. One such way is illustrated in the above show
route. In particular, this show
route’s URI pattern includes an :id
request parameter that becomes part of the URL (e.g., http://localhost:3000/mc_questions/125). When the Rails web server receives a GET request that matches that show
route, the invoked controller action can retrieve the :id
value (e.g., 125
) via the params
hash—specifically, using params[:id]
.
2. Adding a show
Controller Action for McQuestion
Records
In this part, we will add a show
action to the McQuestionsController
class. This is the “to:
” action specified in the above show
route and will be called whenever an incoming HTTP request matches that route.
To begin with, add the show
action, including a respond_to
block, like we’ve seen in previous demos:
def show
respond_to do |format|
format.html { render :show }
end
end
Similar to the index
action, this one will also need to do some retrieving of model objects; however, in the case of the show
action, we will just be retrieving one model object based on the id
in the request URL.
Retrieve the appropriate McQuestion
record by inserting this line before the respond_to
block in the show
action:
question = McQuestion.find(params[:id])
The find
method is yet another model method provided by Rails. In the above usage, it retrieves the saved McQuestion
record with the specified id
.
Once the McQuestion
object have been retrieved, it will need to be passed to the view for rendering.
Similar to the last demo, we will add the locals
hash as an argument to the call to render
to pass the retrieved McQuestion
object to the view, like this:
format.html { render :show, locals: { question: question } }
Note! In the index
action, we had multiple McQuestion
records, so we used the variable name questions
(plural); however, in the show
action, we have only one McQuestion
record, so we use the variable name question
(singular).
3. Adding a show
View for McQuestion
Records
The show
action should display all the important attributes of the mc_question
object (i.e., not the timestamps and not the id
, because that is shown in the URL). Similar to the index
view, we will display the question text followed by a radio button with the answer choices, as depicted in Figure 1.
To start with, create a file app/views/mc_questions/show.html.erb
for the view.
Display the question text by inserting a <p>
block for the question text at the top of view, like this:
<p><%= question.question %></p>
Display answer choices as a radio button (using similar code to that which was used in the index
view) by inserting this code after the question text:
<% choices = [question.answer, question.distractor_1, question.distractor_2] %>
<% choices.each do |c| %>
<div>
<%= radio_button_tag "guess", c, checked = c == question.answer, disabled: true %>
<%= label_tag "guess_#{c}", c %>
</div>
<% end %>
The QuizMe app now provides pages for displaying individual multiple-choice questions (show
pages). For example, opening the URL http://localhost:3000/mc_questions/1 should display a page like the on depicted in Figure 1. Similarly, the URLs http://localhost:3000/mc_questions/2 and http://localhost:3000/mc_questions/3 should display show
pages for the other two questions in the database. Clearly, it isn’t very convenient entering URLs manually to show these records, and in future demos, we will add hyperlinks to make navigating to these pages more convenient.
The QuizMe app now has index
and show
pages that cover the R (“Read”) functionality in CRUD. In upcoming demos, we will add C (“Create”), U (“Update”), and D (“Delete”) functionality to complete the app’s CRUD capabilities.