In this tutorial, we will explore the best practices for designing controllers in Rails. Our goal is to understand how to keep our controllers lean, meaning they should only be responsible for a minimal number of tasks such as handling user input and returning appropriate responses.
By the end of this tutorial, you will learn:
Prerequisites: Basic understanding of Rails architecture and MVC (Model-View-Controller) design pattern.
In Rails, a controller is the component of the application that responds to external requests from the web server, interacting with the models and views to perform the requested operation. It should be as lean as possible, handling only user input and responses.
create
action should only be responsible for creating a resource.class UsersController < ApplicationController
def create
@user = User.new(user_params)
if @user.save
redirect_to @user
else
render 'new'
end
end
end
In this example, the create
action is only responsible for creating a new user. If the user is saved successfully, it redirects to the user page, otherwise, it renders the 'new' form again.
Keep business logic in models: Controllers should be kept slim and not handle business logic. Business logic should be in the model.
Use before actions: Before actions can be used to set up any instance variables that will be used in the action. This helps to keep your actions tidy and avoid repetition.
Don't repeat yourself (DRY): If you find yourself writing the same code in multiple places, consider moving it into a helper or use a before action.
Here is an example of a lean and efficient controller:
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
def index
@users = User.all
end
# GET /users/1
def show
end
# GET /users/new
def new
@user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
def create
@user = User.new(user_params)
if @user.save
redirect_to @user, notice: 'User was successfully created.'
else
render :new
end
end
# PATCH/PUT /users/1
def update
if @user.update(user_params)
redirect_to @user, notice: 'User was successfully updated.'
else
render :edit
end
end
# DELETE /users/1
def destroy
@user.destroy
redirect_to users_url, notice: 'User was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
@user = User.find(params[:id])
end
# Only allow a list of trusted parameters through.
def user_params
params.require(:user).permit(:name, :email)
end
end
In this tutorial, we've covered the best practices for designing controllers in Rails:
To further your learning, you could read about RESTful design, additional Rails conventions, and other design patterns.
Exercise: Create a PostsController
using the best practices we've just covered.
Exercise: Refactor an existing controller in your application to follow these best practices.
Solutions and explanations will depend on the specific controllers and applications, but remember to keep controllers lean, follow the Single Responsibility Principle, move business logic to models, use before actions, and don't repeat yourself.
Happy coding!