🔰

[自己学習]RubyとRailsのコントローラーにおけるインスタンス変数

2025/01/16に公開

✒️初めに

Qiitaで学習内容をまとめてましたが、Zennの使い方も覚えたいため
こちらで学習記録を再開します!


🐥Rubyのインスタンス変数

Rubyのインスタンス変数は、

  • オブジェクトに属する変数
  • クラス内で共有され、オブジェクトごとに異なるデータを保持できる
class Person
  def initialize(name, age)
    @name = name
    @age = age
  end

  def info
    "名前: #{@name}, 年齢: #{@age}"
  end
end

person1 = Person.new("太郎", 30)
person2 = Person.new("花子", 25)

puts person1.info  # => 名前: 太郎, 年齢: 30
puts person2.info  # => 名前: 花子, 年齢: 25

つまり……
各オブジェクトで名前など個々の情報が違うからそれを保持するために、インスタンス変数(@)を使う!


🐥Railsのコントローラーにおけるインスタンス変数

Railsだと「コントローラとビューで共有して使う変数」=インスタンス変数 と思っていたが
これはRubyのインスタンス変数の特性を活用している仕組み。

1. コントローラでのインスタンス変数

Railsのコントローラは、Rubyのクラスとして実装される。

下記の例の場合だと
UsersControllerは ApplicationController から生成された UsersController クラス

class UsersController < ApplicationController
  def show
    # ユーザー情報を取得してインスタンス変数に代入
    @user = User.find(params[:id]) 
  end
end

Railsは、リクエストがあるたびに対応するコントローラークラス(上記ではUsersController)の新しいインスタンス(オブジェクト)が作成される。
そのため、リクエストごとに独立したインスタンスを持つことができる。

流れ
リクエスト1

  • ブラウザが「ユーザーIDが1のデータを見たい!(http://???.com/users/1)」というリクエストを送る。(GET /users/1 HTTP/1.1)
  • Railsがリクエストを受け取り、対応するコントローラ(UsersController)を使う。
  • この時に、Railsは新しい UsersController のインスタンス(/users/1用インスタンス)を作成する。
  • showアクション(メソッド)が呼び出される。
  • @user = User.find(1) が実行され、インスタンス変数(@user)が、この新しく作成された /users/1 用インスタンス内に保存される。
  • このインスタンスはリクエストが終わると破棄される。

リクエスト2

  • 別ブラウザが「ユーザーIDが2のデータを見たい!(http://???.com/users/2)」というリクエストを送る。(GET /users/2 HTTP/1.1)
  • Railsはまた新しい UsersController のインスタンスを作る。
  • @user = User.find(2) が実行され、@user にID2のユーザー情報が保存される。
  • リクエストごとに別のインスタンスを作ることで、リクエストごとに独立したデータを扱えるようになる。また、リクエストが終了すると破棄されるため、リクエスト間でインスタンス変数が共有されることはない。

2. ビューでのインスタンス変数

コントローラーで保存されたデータは、ビュー内でも使用できる。
コントローラ内のインスタンス変数(@user)は、Railsが内部で「ビューに引き渡す」処理を自動的に行っている。
(コントローラのインスタンス変数をassignsという内部ハッシュに保存し、それをビューで利用可能にしている)

コントローラのインスタンス変数がビューの中でそのまま参照できるのは、この仕組みによるもの。

<h1><%= @user.name %>さんのプロフィール</h1>
<p>年齢: <%= @user.age %></p>

📚参考文献

https://docs.ruby-lang.org/ja/latest/doc/spec=2fvariables.html#instance

Discussion