Question

Ruby on Rails Instance Variables vs Local Variables Explained

rubyruby-on-railsvariables

Question

In Ruby on Rails, what is the difference between @title and title? Both appear to be valid variable names. How do I decide when to use a variable with @ and when to use one without it?

Short Answer

By the end of this page, you will understand the difference between instance variables like @title and local variables like title in Ruby and Ruby on Rails. You will learn how scope works, why Rails views often use @variables, and how to choose the right kind of variable in controllers, views, and methods.

Concept

In Ruby, the @ symbol changes the kind of variable you are using.

  • title is a local variable
  • @title is an instance variable

These are not the same variable.

Local variables

A local variable exists only within the current scope, such as:

  • a method
  • a block
  • a small section of code

Example:

def show_name
  name = "Ruby"
  puts name
end

Here, name only exists inside show_name.

Instance variables

An instance variable belongs to a specific object instance. It can usually be accessed by different methods of that same object.

Example:

class Book
  def set_title
    @title = "Eloquent Ruby"
  end

  def print_title
    puts @title
  end
end

If set_title runs first, print_title can use the same @title because both methods are working with the same object.

Why this matters in Rails

In Rails, controllers are objects. When you set an instance variable in a controller action, Rails makes it available to the view for that request.

class PostsController < ApplicationController
  def show
    @title = "Post Details"
    title = "Only inside this method"
  end
end

In the view:

<h1><%= @title %></h1>

@title is available in the view, but title is not.

That is why Rails developers commonly use instance variables in controllers when passing data to views.

Why the concept matters

Understanding variable scope helps you:

  • avoid undefined local variable errors
  • write clearer controller and model code
  • know what data is shared with the view
  • avoid storing data in a wider scope than necessary

A good rule is: use the smallest scope that does the job.

Mental Model

Think of local and instance variables like storage places in a house.

  • title is like a note on your desk. Only the person currently sitting there can use it.
  • @title is like a label attached to the room. Anyone working in that room later can still see it.

In Rails:

  • a controller action can create @title
  • the matching view can read that same @title

But a local variable like title is temporary. It stays only inside the method where it was created.

So if you need data only for a few lines, use a local variable. If you need data to stay attached to the current controller object and be visible to the view, use an instance variable.

Take Quiz

Syntax and Examples

Basic syntax

title = "Hello"     # local variable
@title = "Hello"    # instance variable

Local variable example

def greeting
  message = "Welcome"
  puts message
end

message exists only inside the greeting method.

Instance variable example

class Greeting
  def set_message
    @message = "Welcome"
  end

  def show_message
    puts @message
  end
end

g = Greeting.new
g.set_message
g.show_message

Output:

Welcome

@message is stored in the object, so one method can set it and another can read it.

Rails controller and view example

Controller:

class ArticlesController < ApplicationController
  def index
    @page_title = "All Articles"
    page_count = 10
  end
end

View:

<h1><%= @page_title %></h1>
<p>Articles loaded.</p>

@page_title works in the view. page_count does not, because it is only a local variable inside the index method.

When to choose each

Use a local variable when:

  • the value is only needed inside one method
  • you want to keep scope small and code clear
  • the value is temporary

Use an instance variable when:

  • the value should be available in other methods of the same object
  • in Rails, the value must be available to the view

Step by Step Execution

Consider this Rails controller action:

class PagesController < ApplicationController
  def home
    title = "Local title"
    @title = "Instance title"
  end
end

And this view:

<p><%= @title %></p>
<p><%= title %></p>

What happens step by step

  1. Rails receives a request for the home action.
  2. Rails creates a controller object for that request.
  3. Inside home, title = "Local title" creates a local variable.
  4. That local variable exists only inside the home method.
  5. @title = "Instance title" creates an instance variable on the controller object.
  6. The action finishes.
  7. Rails renders the view connected to that action.
  8. The view can access @title because it is attached to the controller instance.
  9. The view cannot access title because the local variable stopped existing when the method ended.

Result

  • <%= @title %> prints Instance title
  • <%= title %> raises an error because title is not available there

This is the key Rails rule: instance variables are used to pass data from controllers to views.

Real World Use Cases

In Rails controllers

A controller fetches data and exposes it to the view.

def show
  @post = Post.find(params[:id])
end

The view can then display @post.

In forms and edit pages

def edit
  @user = User.find(params[:id])
end

The form uses @user to fill in existing values.

For temporary calculations inside a method

def total_price
  subtotal = 100
  tax = 10
  subtotal + tax
end

subtotal and tax are local variables because they are only needed inside that method.

In Ruby classes outside Rails

Instance variables store object state.

class Counter
  def initialize
    @count = 0
  end

  def increment
    @count += 1
  end
end

Each Counter object keeps its own @count.

In view rendering

Developers often set values like these in controllers:

  • @user
  • @posts
  • @page_title
  • @errors

These are all examples of data that the template needs to render.

Take Quiz

Real Codebase Usage

In real Rails projects, developers usually prefer local variables by default and use instance variables only when data must be shared with the view or across methods of the same object.

Common controller pattern

class ProductsController < ApplicationController
  def show
    @product = Product.find(params[:id])
  end
end

This is standard because the view needs @product.

Common service or model pattern

def discounted_price(price)
  discount = 0.2
  price - (price * discount)
end

discount stays local because nothing outside the method needs it.

Using instance variables for object state

class ReportBuilder
  def initialize(records)
    @records = records
  end

  def build
    @records.map(&:name)
  end
end

Here @records is part of the object's state.

Guard clauses with locals

def formatted_name(user)
  return "Guest" if user.nil?

  first = user.first_name
  last = user.last_name
  "#{first} #{last}"
end

first and last are local because they are only useful in this method.

Avoiding unnecessary instance variables

Some beginners write this:

def calculate
  @a = 5
  @b = 10
  @result = @a + @b
end

Often this is better:

def calculate
  a = 5
  b = 10
  a + b
end

This avoids storing temporary values on the object when they are not needed later.

Practical guideline

  • Use local variables for temporary work
  • Use instance variables for object state or controller-to-view data
  • Keep scope as small as possible

Common Mistakes

1. Expecting a local variable to be available in the view

Broken example:

class PostsController < ApplicationController
  def index
    title = "Posts"
  end
end
<h1><%= title %></h1>

Why it fails:

  • title is local to the controller method
  • the view cannot access it

Fix:

def index
  @title = "Posts"
end

2. Using instance variables for everything

Broken style:

def sum
  @x = 1
  @y = 2
  @z = @x + @y
end

Why it is a problem:

  • it makes object state larger than necessary
  • it can make code harder to reason about

Better:

def sum
  x = 1
  y = 2
  x + y
end

3. Forgetting that instance variables belong to an object

class User
  def set_name
    @name = "Mina"
  end
end

If you create a new object, it will not automatically have the same @name as another object. Instance variables are stored per object.

4. Reading an instance variable before setting it

class Example
  def show
    puts @value
  end
end

In Ruby, an unset instance variable is nil.

That may not crash immediately, but it can cause bugs if you expected a real value.

5. Confusing instance variables with class variables

  • @name is an instance variable
  • @@name is a class variable

These behave differently. Beginners should not assume they are interchangeable.

6. Reusing the same name and assuming they are linked

title = "Local"
@title = "Instance"

These are two separate variables with similar names, not one shared value.

Comparisons

Variable typeExampleScopeCommon Rails use
Local variabletitleOnly within the current method or blockTemporary calculations, helper values
Instance variable@titleAvailable to the current object across methodsPassing data from controller to view

Local variable vs instance variable

  • Local variable: short-lived and limited in scope
  • Instance variable: attached to an object and available to that object's methods

In a Rails controller

CodeAvailable in view?
title = "Hello"No
@title = "Hello"Yes

Related variable types in Ruby

TypeExampleMeaning
Local variablenameExists in current scope
Instance variable@nameBelongs to one object
Class variable@@nameShared across a class hierarchy
Global variable$nameAccessible almost everywhere
ConstantNAMEIntended not to change

For most beginner Rails code, the most important comparison is local vs instance variable.

Take Quiz

Cheat Sheet

name = "Ruby"     # local variable
@name = "Ruby"    # instance variable
  • name and @name are different variables
  • Local variables exist only in the current method or block
  • Instance variables belong to an object
  • In Rails controllers, instance variables are available in views
  • Use local variables for temporary values
  • Use instance variables for shared object state or controller data for templates
  • Unset instance variables are nil

Quick rule

  • Need it only inside one method? Use title
  • Need it in the view or across object methods? Use @title

Rails example

def show
  @post = Post.find(params[:id]) # view can use this
  post_count = 5                 # view cannot use this
end

Common error

<%= title %>

This will fail if title was only a local variable in the controller action.

FAQ

What does @ mean before a variable in Ruby?

It means the variable is an instance variable, which belongs to a specific object.

What is the difference between title and @title in Rails?

title is a local variable and only exists in the current scope. @title is an instance variable and is available to the controller object and its view.

Why do Rails views often use @variables?

Because Rails exposes controller instance variables to the view template for rendering.

Should I always use @variables in a Rails controller?

No. Use instance variables only for data the view needs. Use local variables for temporary values inside the action.

What happens if I use an instance variable without setting it?

Its value is nil.

Can two methods in the same class use the same instance variable?

Yes, if they run on the same object instance.

Is @title the same as a global variable?

No. A global variable starts with $, not @. Instance variables are limited to one object.

How do I choose between local and instance variables?

Choose the smallest scope that works. If only one method needs it, use a local variable. If the object or the view needs it, use an instance variable.

Take Quiz

Mini Project

Description

Build a small Rails-style example that shows which variables are available inside a method and which are available in a view. This project helps you practice the difference between local variables and instance variables in a realistic controller/view setup.

Goal

Create a controller action that sends a page title and a list of posts to a view using instance variables, while keeping temporary calculations as local variables.

Requirements

  • Create a controller action named index
  • Store the page title in an instance variable
  • Store a list of post titles in an instance variable
  • Use at least one local variable for a temporary calculation
  • Render the instance variables in an ERB view
Take Quiz

Keep learning

Related questions

View more