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. πŸ’Ž

ChatGPT Image Feb 19, 2026, 03_53_48 PM


πŸ“Œ 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::API instead 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.