Ruby on Rails Interview Questions and Answers — Controller — Part 2

Gokul
9 min readOct 21, 2023

--

  • Describe the purpose and usage of the before_action, around_action and after_action callbacks in Rails controllers.
  • How can you redirect users to different pages or actions in a controller?
  • What is the purpose of the flash object in Rails controllers, and when is it useful?
  • How do you handle exceptions and errors gracefully in Rails controllers?
  • What is the difference between rendering a view with render and performing a redirect with redirect_to?

6. Describe the purpose and usage of the before_action, around_action and after_action callbacks in Rails controllers.

In Ruby on Rails controllers, there are several callback methods that allow you to run code at different points in the request-response lifecycle. These callbacks help you manage the flow of your controller actions and are commonly used for tasks such as authentication, authorization, logging, and more. Let’s explore the purposes and usages of the before_action, around_action, and after_action callbacks:

before_action

Purpose: The before_action callback is used to execute code before the main action method is invoked. It is typically used for tasks that need to be performed as preconditions for one or more controller actions, such as authentication or setting up instance variables.

Usage: You define before_action callbacks in your controller class, specifying the methods to run before specific actions or globally across all actions in the controller.

class ApplicationController < ActionController::Base
before_action :authenticate_user, only: [:edit, :update, :destroy]

def authenticate_user
unless current_user
redirect_to login_path
end
end
end

In this example, the before_action called authenticate_user ensures that the user is authenticated before executing the edit, update, or destroy actions.

around_action

Purpose: The around_action callback allows you to wrap the execution of an action with custom code. It can be used to modify the request or response before and after the action is executed. It's particularly useful when you need to perform tasks both before and after an action and have more fine-grained control than before_action and after_action provide.

Usage: You define around_action callbacks in your controller class, specifying the method to run before and after an action.

class ApplicationController < ActionController::Base
around_action :log_request_time

def log_request_time
start_time = Time.now
yield # Execute the action
end_time = Time.now
Rails.logger.info("Request took #{end_time - start_time} seconds.")
end
end

In this example, the around_action called log_request_time measures the time it takes to execute an action and logs that information before and after the action is executed.

after_action

Purpose: The after_action callback is used to execute code after the main action method has been invoked and the response has been sent to the client. It is commonly used for tasks like logging, resource cleanup, or modifying the response.

Usage: You define after_action callbacks in your controller class, specifying the methods to run after specific actions or globally.

class ApplicationController < ActionController::Base
after_action :log_request

def log_request
Rails.logger.info("Request completed for #{request.path}")
end
end

In this example, the after_action called log_request logs information about the completed request after the response has been sent.

Common Use Cases

Authentication and Authorization: before_action is commonly used to enforce authentication and authorization checks before allowing access to specific controller actions.

Logging and Metrics: before_action and after_action can be used for logging requests, response times, and other metrics.

Resource Cleanup: after_action is useful for performing cleanup tasks like closing database connections or releasing resources.

Complex Request and Response Manipulation: around_action is helpful when you need to modify the request or response in a complex way before and after the main action.

Customization and Reusability: These callbacks allow you to encapsulate and reuse common behavior across multiple actions and controllers, promoting code modularity and maintainability.

7. How can you redirect users to different pages or actions in a controller?

In a Ruby on Rails controller, you can redirect users to different pages or actions using the redirect_to method. The redirect_to method is used to send an HTTP redirect response to the client's browser, instructing it to navigate to a different URL. You can specify various destinations for the redirect, including other actions within the same controller, external URLs, or named routes. Here are some common ways to use redirect_to:

Redirect to a Different Action in the Same Controller

You can specify the action as a symbol to redirect users to a different action within the same controller.

def some_action
# ...
redirect_to :another_action
end

Redirect to a Different Controller’s Action

You can redirect to an action in a different controller by specifying both the controller and action as a hash.

def some_action
# ...
redirect_to controller: 'other_controller', action: 'other_action'
end

Redirect to an External URL

To redirect users to an external URL, simply provide the full URL as a string.

def some_action
# ...
redirect_to 'https://www.example.com'
end

Redirect to a Named Route

If you have defined named routes in your routes configuration, you can use the named route as an argument to redirect_to.

def some_action
# ...
redirect_to users_path
end

Redirect with Flash Messages

You can include flash messages when redirecting to provide feedback to the user. Flash messages are often used to display success or error messages after a redirect.

def some_action
# ...
flash[:notice] = 'Successfully completed the action.'
redirect_to some_other_path
end

Redirect with Status Codes

By default, redirect_to issues a 302 Found status code, indicating a temporary redirect. You can specify a different HTTP status code using the :status option.

def some_action
# ...
redirect_to some_path, status: 301 # 301 Moved Permanently
end

Remember to use the appropriate method to trigger the redirect (e.g., redirect_to), and it's generally a good practice to use named routes whenever possible to make your code more maintainable and robust.

8. What is the purpose of the flash object in Rails controllers, and when is it useful?

The flash object is a part of the session and serves as a way to store and display short-lived, one-time messages to users across different HTTP requests. The primary purpose of the flash object is to provide a way to communicate information to users as they navigate through your application. It is particularly useful for showing success messages, error messages, or other notifications after a user takes an action.

The flash object is cleared automatically after it's displayed once, ensuring that the message is not displayed again on subsequent requests. Here are some common use cases and situations where the flash object is useful in Rails controllers:

Success Messages

You can use the flash object to provide positive feedback to the user after they have successfully performed an action, such as creating a new account, updating a profile, or submitting a form.

def create
@user = User.new(user_params)
if @user.save
flash[:notice] = 'User successfully created!'
redirect_to users_path
else
render 'new'
end
end

Error Messages

When there is a validation error or some other issue with a user’s input, you can use the flash object to display error messages. This helps users understand what went wrong and how to correct it.

def update
if @user.update(user_params)
flash[:notice] = 'User profile updated successfully.'
redirect_to @user
else
flash[:alert] = 'Error updating user profile.'
render 'edit'
end
end

Redirect After Actions

After a user submits a form or performs an action that triggers a redirect to another page, you can use the flash object to provide context for the redirection. This is especially helpful when you want to display messages on the redirected page.

def destroy
@user.destroy
flash[:notice] = 'User deleted successfully.'
redirect_to users_path
end

Flash Alerts

You can use the flash object to display important alerts, warnings, or notices to users. These messages can provide critical information or instructions when needed.

def some_action
# ...
flash[:alert] = 'This is an important notice!'
redirect_to some_path
end

9. How do you handle exceptions and errors gracefully in Rails controllers?

Handling exceptions and errors gracefully in Ruby on Rails controllers is important to ensure that your application provides a good user experience and doesn’t reveal sensitive information to users. Here are some best practices for handling exceptions and errors in Rails controllers:

Rescue From Exceptions

You can use the rescue_from method in your controller to handle exceptions globally for specific exceptions.

class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found

def record_not_found
render plain: 'Record not found', status: :not_found
end
end

In the example above, if a RecordNotFound exception is raised, the record_not_found method will be called to handle the exception. You can create similar methods for other exceptions you want to handle.

Custom Error Pages

You can create custom error pages to provide a consistent and user-friendly error experience. To do this, you can use the rescue_from method and specify the HTML error pages you want to render.

class ApplicationController < ActionController::Base
rescue_from ActionController::RoutingError, with: :render_404

def render_404
render file: "#{Rails.root}/public/404.html", layout: false, status: :not_found
end
end

In this case, when a routing error occurs, Rails will render your custom 404 page.

Use the flash Object

As mentioned in the previous answer, you can use the flash object to provide error messages and feedback to users.

def create
@user = User.new(user_params)
if @user.save
flash[:notice] = 'User successfully created!'
redirect_to users_path
else
flash[:alert] = 'Error creating user.'
render 'new'
end
end

Displaying flash messages allows you to inform users about errors or issues in a user-friendly way.

Logging Errors

Log errors using Rails’ built-in logging mechanisms (e.g., logger.error) to keep track of what went wrong. You can also use tools like error tracking services or gems like Sentry or Rollbar to centralize error monitoring and receive notifications when exceptions occur.

Handle Unexpected Errors

For unhandled exceptions, Rails provides a default error page with a generic error message. You can customize this page on your public directory (e.g., public/500.html) and use the rescue_from method to specify how to handle unhandled exceptions.

Use Validation and Error Handling Methods

In your model, use validations to handle data-related errors and render the form again with appropriate error messages. In your controller, you can check the object’s validity and respond accordingly.

def create
@user = User.new(user_params)
if @user.save
flash[:notice] = 'User successfully created!'
redirect_to users_path
else
render 'new'
end
end

10. What is the difference between rendering a view with render and performing a redirect with redirect_to?

render

Generates an HTML response without changing the URL, often used for rendering views within the same action.

Rendering a View: When you use render in a controller action, you are instructing Rails to generate an HTML response by rendering a specific view template. This means the controller action will prepare data for the view, and the view template will be rendered, generating an HTML response that is sent to the client's browser.

Internal Action: render keeps the request within the same controller action. It's typically used when you want to show a different view without changing the URL in the browser. For example, when there are validation errors in a form submission, you might render the form again with error messages.

def create
@user = User.new(user_params)
if @user.save
redirect_to users_path
else
render 'new' # Render the 'new' view template
end
end

redirect_to

Issues an HTTP redirect, which causes the client’s browser to make a new request to a different URL, often used for navigation and to prevent form resubmissions.

HTTP Redirect: When you use redirect_to in a controller action, you are instructing Rails to send an HTTP redirect response to the client's browser with a new URL. The client's browser will make a new request to the specified URL. This can be a URL within your application, an external URL, or even a named route.

Change of URL: redirect_to is used to navigate the user to a different URL or action, often after a successful form submission or after performing some action. It is a common way to implement the Post-Redirect-Get (PRG) pattern, which helps prevent form resubmissions when the user refreshes the page.

def create
@user = User.new(user_params)
if @user.save
redirect_to users_path # Redirect to a different URL
else
render 'new' # Render the 'new' view template
end

I appreciate you taking the time to read this. Please follow me on Medium and subscribe to receive access to exclusive content in order to keep in touch and continue the discussion. Happy Reading..!

--

--

Gokul

Consultant | Freelancer | Ruby on Rails | ReactJS