Here's the third quiz for people who are just getting started learning web-application development. This revisits the basics of MVC, implementing basic user-authentication and polymorphic associations.
id user_id photo_id video_id post_id 1 4 12 2 7 3 3 2 6
A1: Rendering a view template happens as (the final) part of a single HTTP request, whereas redirecting means end of a request and initiation a whole new request. And because of that, redirecting would not enable use of instance variables in the view templates unlike direct rendering.
A2: Using a hash referenced in the layout would be the easiest way to display messages if redirecting. For example:
flash[:notice] = 'You have successfully updated the profile'
flash[:error] = 'The login credentials you entered are incorrect'
A3: For generic messages, using the same hash as described in A2 above would work. If error messages on a model-object stored in an instance variable need to be displayed, that instance variable can be used directly in the view template using something like
<% if model_obj.errors.any? %>
<div class='alert alert-error span8'>
<h5>Please fix the errors below to submit successfully:</h5>
<% model_obj.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
<% end %>
A4: Passwords should definitely never be stored directly as strings in the database. They should be auto converted to complex strings (obfuscated) using a dedicated gem (like bcrypt-ruby). Such a gem can help obfuscate the user-entered password using the same mechanism to obfuscate the originally set password. Thus the comparison between the user entered and originally set password can happen indirectly through the obfuscated strings. This obfuscation is one-way, that means the stored string cannot be converted back to the actual password string.
In case of the bcrypt-ruby gem, the database table for the model needs to have a column named 'password_digest' that can hold a string. The model itself needs to have the
has_secure_password validation declared in its class-definition. bcrypt-ruby gives a method named
authenticate for the model-object which can be used to match the user-entered password to the stored one.
A5: If a helper method defined in the ApplicationController class (which each of the controllers inherit from) needs to be used by both the views, and the controllers, the
helper_method needs to be called in the ApplicationController class definition with the helper-method names passed to it as arguments (as
:symbols). So, a line like the one below in the ApplicationController class definition
helper_method :current_user, :logged_in?
will allow the methods
logged_in? to be used in both views and controllers. Note that a call to
helper_method is not necessary if these only need to be used in the controllers.
A6: 'Memoization' (a play on the word 'memoir') is an optimization technique used to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same operation is requested repeatedly.
It can be implemented in Ruby using the operator
||= to assign a value to an instance variable. This can be used effectively to store results from a repeated database query (which can be quite performance intensive). The statement below is 'memoization' in action:
@current_user ||= User.find(session[:user_id]) if session[:user_id]
current_user instance variable is already populated (say, from a previous call to this statement), the cached result will be returned and evaluation of the right side of the above expression will be avoided.
A7: The rendering and submission of new comment form (Comments#new and Comments#create actions) should be allowed only if a user is logged in. This can be achieved by a common helper method that checks whether a valid user is logged in. This method will be defined in the parent controller class ApplicationController. This method can be called in the Comments controller class using the
before_action keyword which will trigger checking of a valid user before executing certain actions.
before_action :logged_in?, only: [:new, :create]
1 2 3 4
1 2 3 4 5 6
1 2 3 4
1 2 3 4
1 2 3 4
A10: Entity Relationship Diagrams show individual ActiveRecord models and their association with each other. Individual models are represented as blocks and also show the columns that model's database table needs to have. These are really handy when we are setting up the database models and associations between them.
See the ERD below for the PostIt application (Courtesy - Tealeaf Academy):