Ruby on Rails Controller Mastery
π Ruby on Rails Controller Mastery
Write Clean, Scalable & Production-Ready Controllers Like a Pro π
Controllers are the brain π§ of a Rails application. Poorly written controllers lead to fat controllers, bugs, and unmaintainable code. Well-designed controllers give you clarity, performance, and scalability.
Letβs master Rails Controllers with principles, tricks, hacks, best practices, and mistakes to avoid β all with real examples π
π― What Is a Rails Controller (Quick Recap)
A controller:
- Receives HTTP requests π
- Talks to models π¦
- Decides what response to send (HTML/JSON/etc.) π€
π Golden Rule:
Controllers should orchestrate β not compute.
π§ Core Principles of Controller Mastery
1οΈβ£ Skinny Controller, Fat Model (or Service) ποΈββοΈ
Controllers should be thin. Business logic belongs elsewhere.
β Bad
def create
user = User.new(user_params)
user.token = SecureRandom.hex
user.save!
end
β Good
def create
UserSignupService.new(user_params).call
end
π Move logic to:
- Models
- Service Objects
- Query Objects
2οΈβ£ One Action = One Responsibility π―
Each action should do ONE thing only.
β Bad
def create
@user = User.create(user_params)
send_email
track_analytics
end
β Good
def create
@user = User.create!(user_params)
UserMailer.welcome(@user).deliver_later
end
3οΈβ£ RESTful Controllers Are Non-Negotiable π
Stick to Rails conventions:
| Action | Purpose |
|---|---|
| index | List |
| show | View |
| new | Form |
| create | Save |
| edit | Edit form |
| update | Update |
| destroy | Delete |
π Convention > Configuration
π§© Controller Best Practices (With Hacks)
4οΈβ£ Use before_action Wisely β οΈ
DRY your code, but donβt overuse.
before_action :set_user, only: [:show, :edit, :update]
def set_user
@user = User.find(params[:id])
end
π¨ Avoid:
- Too many callbacks
- Hidden side effects
5οΈβ£ Strong Parameters Are Mandatory π
Never trust user input.
def user_params
params.require(:user).permit(:name, :email)
end
π₯ Pro Hack: Use fetch for APIs
params.fetch(:user, {}).permit(:name)
6οΈβ£ Use respond_to for Multiple Formats π
Perfect for APIs + Web apps.
respond_to do |format|
format.html
format.json { render json: @users }
end
7οΈβ£ Render vs Redirect β Know the Difference π¦
| Method | What it does |
|---|---|
| render | Same request |
| redirect_to | New request |
β Buggy
redirect_to users_path
render :index # β Double render error
8οΈβ£ Use Namespaced Controllers for APIs π§©
Clean separation.
module Api
module V1
class UsersController < ApplicationController
def index
render json: User.all
end
end
end
end
π Advanced Controller Hacks
9οΈβ£ Use concerns for Shared Logic β»οΈ
module Authenticable
extend ActiveSupport::Concern
included do
before_action :authenticate_user!
end
end
class DashboardController < ApplicationController
include Authenticable
end
π Pagination at Controller Level π
@users = User.page(params[:page]).per(10)
Never load thousands of records π΅βπ«
1οΈβ£1οΈβ£ Authorization in Controllers π‘οΈ
With Pundit:
authorize @post
With CanCanCan:
authorize! :update, @post
1οΈβ£2οΈβ£ Handle Errors Gracefully π¨
rescue_from ActiveRecord::RecordNotFound do
render file: "public/404.html", status: :not_found
end
π₯ Pro tip: Centralize error handling in ApplicationController.
β οΈ Common Controller Mistakes to Avoid
β 1. Fat Controllers
π Business logic inside controller = β
β 2. Direct SQL in Controllers
User.where("age > 18") # β
Move queries to:
- Scopes
- Query objects
β 3. Overusing Callbacks
Too many before_action makes code hard to debug.
β 4. Ignoring Security
- Missing strong params
- No authentication
- No authorization
β 5. Returning Models Directly in APIs
render json: @user # β
Use:
- Serializers
- JBuilder
- Blueprinter
ποΈ Ideal Controller Structure (Pro Template)
class UsersController < ApplicationController
before_action :set_user, only: %i[show update destroy]
def index
@users = User.all
end
def show; end
def create
@user = User.create!(user_params)
end
private
def set_user
@user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:name, :email)
end
end
Clean β¨ Readable π Maintainable π§
π§ Final Controller Mastery Rules (Remember This π‘)
β Controllers orchestrate, not calculate β Keep actions small β Follow REST & Rails conventions β Extract logic early β Secure everything
π¬ βA great Rails app is judged by how boring its controllers are.β
© Lakhveer Singh Rajput - Blogs. All Rights Reserved.