基本

Ruby on Railsのビューで変数を使う方法

Ruby on Railsでは、コントローラーで定義したインスタンス変数(@で始まる変数)をビューテンプレートで使用できます。これにより、データベースから取得したデータや計算結果をビューに渡し、動的なHTMLページを生成できます。この記事では、コントローラーからビューへのデータ受け渡し方法と、ビュー内での変数の使い方を解説します。

基本的な使い方

コントローラーのアクション内でインスタンス変数を定義すると、対応するビューで自動的にその変数が使えるようになります。

app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    @message = "Hello, Rails!"
  end
end
app/views/posts/index.html.erb
<p><%= @message %></p>

ビュー側では<%= @変数名 %>と記述することで、コントローラーで設定した値がHTMLに出力されます。=を付けないと値が出力されないので注意してください。

複数の変数を渡す

1つのアクションから複数のインスタンス変数をビューに渡すことができます。文字列だけでなく、数値、配列、ハッシュなど、あらゆるRubyオブジェクトを渡せます。

app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    @title = "投稿一覧"
    @numbers = [1, 2, 3, 4, 5]
    @user = {
      name: "山田太郎",
      age: 30,
      email: "yamada@example.com"
    }
  end
end
app/views/posts/index.html.erb
<h1><%= @title %></h1>

<h2>数値リスト</h2>
<ul>
  <% @numbers.each do |number| %>
    <li><%= number %></li>
  <% end %>
</ul>

<h2>ユーザー情報</h2>
<p>名前: <%= @user[:name] %></p>
<p>年齢: <%= @user[:age] %></p>
<p>メール: <%= @user[:email] %></p>

モデルオブジェクトの受け渡し

実際の開発では、データベースから取得したモデルオブジェクトをビューに渡すのが最も一般的な使い方です。

app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def show
    @post = Post.find(params[:id])
    @comments = @post.comments
  end
end
app/views/posts/show.html.erb
<h1><%= @post.title %></h1>
<div class="content">
  <%= @post.content %>
</div>

<h2>コメント (<%= @comments.count %>件)</h2>
<% @comments.each do |comment| %>
  <div class="comment">
    <strong><%= comment.user.name %></strong>
    <p><%= comment.body %></p>
    <small><%= comment.created_at.strftime("%Y/%m/%d %H:%M") %></small>
  </div>
<% end %>

モデルオブジェクトの属性には@post.titleのようにドット記法でアクセスできます。関連するデータ(この例ではコメント)もまとめて取得して渡すことが可能です。

条件に応じたデータの切り替え

パラメータや条件に応じて、異なるデータをビューに渡すこともよくあるパターンです。

app/controllers/products_controller.rb
class ProductsController < ApplicationController
  def index
    @category = params[:category]

    if @category.present?
      @products = Product.where(category: @category)
      @page_title = "#{@category}の商品一覧"
    else
      @products = Product.all
      @page_title = "全商品一覧"
    end
  end
end
app/views/products/index.html.erb
<h1><%= @page_title %></h1>

<% if @products.any? %>
  <% @products.each do |product| %>
    <div class="product">
      <h3><%= product.name %></h3>
      <p><%= product.description %></p>
      <p class="price"><%= number_to_currency(product.price) %></p>
    </div>
  <% end %>
<% else %>
  <p>該当する商品がありません。</p>
<% end %>
ポイント

インスタンス変数(@で始まる変数)のみがビューに渡されます。ローカル変数(@なしの変数)はビューからアクセスできません。

注意

ビューに渡すインスタンス変数は必要最小限にしましょう。不要なデータまで渡すと、メモリ消費が増え、ビューのテストも複雑になります。また、変数名は明確に命名し、コードの可読性を保つことが重要です。

まとめ

  • コントローラーでインスタンス変数(@変数名)を定義するとビューで使える
  • ビューでは<%= @変数名 %>で変数の値を出力する
  • 文字列、数値、配列、ハッシュ、モデルオブジェクトなど様々な型のデータを渡せる
  • モデルオブジェクトの属性にはドット記法(@post.title)でアクセスする
  • ローカル変数はビューに渡されないので、必ず@を付ける
  • 渡す変数は必要最小限にし、明確な命名を心がける