Mastering Action Controller in Ruby on Rails
π Mastering Action Controller in Ruby on Rails
The Brain Behind Your Web Requests π§ β‘
When you hit a URL in a Rails app, magic happens. But that βmagicβ is actually powered by one of the most important components of Rails β Action Controller.
If youβre serious about building scalable, clean, and high-performance Rails apps, mastering Action Controller is non-negotiable. Letβs break it down deeply with examples, hacks, performance tips, and common mistakes to avoid. π
π What is Action Controller?
In Ruby on Rails, Action Controller is the component that:
- Receives HTTP requests π
- Processes parameters π₯
- Interacts with models ποΈ
- Renders responses (HTML, JSON, XML, etc.) π€
It lives between the router and the view layer.
Client β Router β Controller β Model β View β Response
It follows the MVC (Model-View-Controller) architecture β where the Controller acts as the traffic manager π¦.
π₯ How Action Controller Works (Step-by-Step)
Letβs walk through a request lifecycle:
1οΈβ£ User hits URL
GET /users/1
2οΈβ£ Router maps it
get '/users/:id', to: 'users#show'
3οΈβ£ Controller action executes
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
end
end
4οΈβ£ View renders automatically
app/views/users/show.html.erb
5οΈβ£ Response sent back π―
Rails automatically renders the view matching the action unless told otherwise.
π§ Core Responsibilities of Action Controller
1οΈβ£ Parameters Handling
params[:id]
params[:user][:email]
Strong Parameters for security:
def user_params
params.require(:user).permit(:name, :email)
end
π Prevents mass assignment vulnerabilities.
2οΈβ£ Rendering & Redirecting
Render explicitly
render :edit
render json: @user
render status: 422
Redirect
redirect_to users_path
redirect_to @user
π‘ Hack: Use head :ok when no body is needed.
3οΈβ£ Filters (Callbacks) ποΈ
Filters help execute code before/after actions.
before_action :authenticate_user
after_action :log_activity
around_action :wrap_transaction
Example:
before_action :set_user, only: [:show, :edit, :update]
def set_user
@user = User.find(params[:id])
end
4οΈβ£ Sessions & Cookies πͺ
session[:user_id] = @user.id
cookies[:theme] = "dark"
Encrypted cookies:
cookies.encrypted[:user_id] = @user.id
5οΈβ£ Flash Messages π¬
flash[:notice] = "User created successfully!"
flash[:alert] = "Something went wrong."
6οΈβ£ Responding to Multiple Formats
respond_to do |format|
format.html
format.json { render json: @user }
format.xml { render xml: @user }
end
Perfect for APIs + Web in same controller.
β‘ Hidden Features & Powerful Tricks
π₯ 1. helper_method
Expose controller methods to views:
helper_method :current_user
π₯ 2. rescue_from
Centralized error handling:
rescue_from ActiveRecord::RecordNotFound, with: :not_found
def not_found
render file: 'public/404.html', status: :not_found
end
Clean & production-ready π
π₯ 3. skip_before_action
skip_before_action :authenticate_user, only: [:index]
π₯ 4. Custom Responders
You can override default behavior:
def create
@user = User.new(user_params)
if @user.save
render_success
else
render_error
end
end
π₯ 5. Use concerns in Controllers
module Trackable
extend ActiveSupport::Concern
included do
before_action :track_user
end
end
Clean reusable logic π‘
π Performance Optimization Techniques
β‘ 1. Avoid Heavy Logic in Controllers
β Bad:
def index
users = User.all.select { |u| u.active? }
end
β Good:
def index
@users = User.active
end
Move logic to model.
β‘ 2. Use includes to Avoid N+1 Queries
@users = User.includes(:posts)
Huge performance boost for APIs π
β‘ 3. Use before_action wisely
Donβt load data unnecessarily.
β Avoid:
before_action :set_user
(for all actions)
β‘ 4. Use Streaming for Large Responses
include ActionController::Live
For CSV exports or large responses.
β‘ 5. Use Caching π§
caches_action :index
Or fragment caching in views.
𧨠Common Mistakes to Avoid
β 1. Fat Controllers
If your controller exceeds 200+ lines β danger zone π¨
π Move logic to:
- Models
- Service Objects
- Concerns
β 2. Skipping Strong Params
Never do:
User.create(params[:user])
Security risk π₯
β 3. Business Logic in Controller
Controllers should orchestrate, not calculate.
β 4. Too Many Instance Variables
Keep views clean. Use presenters if needed.
β 5. Not Handling Errors Properly
Always handle:
- 404
- 422
- 500
Use rescue_from.
π― Advanced Example (Clean Controller Design)
class UsersController < ApplicationController
before_action :set_user, only: %i[show update destroy]
def index
@users = User.active.includes(:posts)
end
def create
@user = Users::CreateService.call(user_params)
if @user.persisted?
redirect_to @user, notice: "User created!"
else
render :new, status: :unprocessable_entity
end
end
private
def set_user
@user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:name, :email)
end
end
π₯ Thin π₯ Secure π₯ Performant π₯ Scalable
π§ Pro-Level Optimization Strategy
If youβre building APIs or high-traffic apps:
- Use
ActionController::APIinstead of full stack - Disable unused middleware
- Use pagination (Kaminari / Pagy)
- Cache JSON responses
- Use background jobs for heavy work
- Benchmark using rack-mini-profiler
π Final Thoughts
Action Controller is not just a file where you write CRUD actions.
It is:
β The request brain β The security gatekeeper β The response builder β The traffic controller
Master it β and your Rails apps become cleaner, faster, and more professional. π
© Lakhveer Singh Rajput - Blogs. All Rights Reserved.