Rails の index, show アクションを理解しよう
- 学習の目標
- はじめに
- コントローラの中身を書き換える
- indexアクション - すべてのレコードを取得
- showアクション - 特定のレコードを1つ取り出す
- インスタンス変数の役割を理解する
- ビューでのデータの表示方法
- まとめ
学習の目標
本章では、以下の内容を学習します。
- コントローラのアクションがどのように動作するかを理解する
- index アクションの役割とデータ取得方法を学ぶ
- show アクションの役割とデータ取得方法を学ぶ
- モデルからデータを取得する基本的な方法を習得する
- コントローラとビューの連携の仕組みを理解する
はじめに
前回は scaffold という仕組みを使って、Railsの基本である7つのアクションをコントローラに作り、データの作成・表示・編集・削除という基本機能を一気に作りました。
今回は、コントローラに作られたアクションがどう動いているのかを、詳しく見ていきましょう。まずは index, show アクションから見ていきます。
Railsでもっとも大事な部分ですので大変かもしれません。一回で理解することが難しい内容ですので、何回か復習しながら少しずつ理解してみてください。
コントローラの中身を書き換える
scaffoldで作られる機能はかなり整っているのですが、Railsをはじめて学習する上では少し余分な機能まで含まれています。そのため、わかりやすいポイントだけに絞ったソースコードに置き換えてしまいましょう。
app/controllers/posts_controller.rb
ファイルを開き、中身を消して、以下のように書き換えてください。
class PostsController < ApplicationController
# GET /posts
def index
@posts = Post.all
end
# GET /posts/1
def show
@post = Post.find(params[:id])
end
# GET /posts/new
def new
@post = Post.new
end
# POST /posts
def create
@post = Post.new(post_params)
if @post.save
redirect_to post_path(@post), notice: "Post was successfully created."
else
render :new
end
end
# GET /posts/1/edit
def edit
@post = Post.find(params[:id])
end
# PATCH/PUT /posts/1
def update
@post = Post.find(params[:id])
if @post.update(post_params)
redirect_to post_path(@post), notice: "Post was successfully updated."
else
render :edit
end
end
# DELETE /posts/1
def destroy
@post = Post.find(params[:id])
@post.destroy!
redirect_to posts_path, notice: "Post was successfully destroyed."
end
private
def post_params
params.require(:post).permit(:title, :body)
end
end
一部削除や調整をしているものの、scaffoldで作った機能とほぼ同じと思っていただいて大丈夫です。今後、scaffoldを使わずにコントローラを作る場合は、上記のような形が基本となります。
では、今回は index, show アクションについて詳しく見ていきましょう。
indexアクション - すべてのレコードを取得
indexアクションの役割
まず index というアクションがあります。indexアクションは、モデルのデータをすべて取得して一覧表示するための処理です。
def index
@posts = Post.all
end
この短いコードですが、とても重要なことをしています。Post.all
を呼び出して、Post モデルに保存されたすべてのレコード(データ)を取り出し、それを @posts というインスタンス変数に格納しています。
モデル名とテーブル名の関係
モデル名は、テーブル名から「s」を取って、最初のアルファベットを大文字にします。例えば:
- posts テーブル → Post モデル
- users テーブル → User モデル
これはRailsの規約の一つで、このルールに従うことで、特別な設定をしなくてもRailsが自動的にテーブルとモデルを関連付けてくれます。
Post.allとは
Railsでは、モデル名に対して .all
と書くと、そのモデルに対応するテーブルからすべてのデータを取り出すことを意味します。
Post.all
を実行すると、Railsは内部的にSQL文を生成し、データベースからすべての投稿データを取得してきます。生成されるSQL文は次のようなものです。
SELECT * FROM posts;
コントローラからビューへの変数の受け渡し
ここで定義した @posts という変数は、アクション内で定義されたインスタンス変数です。Railsでは、コントローラのアクション内で定義されたインスタンス変数(@で始まる変数)は、自動的に対応するビューで利用可能になります。
そのため、indexアクションによって表示されるビュー(app/views/posts/index.html.erb
)からも、先ほどの@posts
というインスタンス変数を使うことができます。
結果的に、indexアクションに対応するビュー、つまりページの中では、すべての投稿データを表示することができるようになるのです。
http://127.0.0.1:3000/posts
というURLにアクセスすると、indexアクションが実行され、対応するビューが表示されます。
showアクション - 特定のレコードを1つ取り出す
showアクションの役割
show アクションは、URLに含まれた id を使って特定のレコードを1つだけ取得します。
def show
@post = Post.find(params[:id])
end
Post.findとは
Post.find(params[:id])
は、指定されたIDを持つ投稿を1つだけ取得するためのメソッドです。
.find
は、特定のIDを持つデータを1つだけ取得するメソッドで、Railsでモデルに対して使えるメソッドとなっています。生成されるSQL文は次のようなものです。
SELECT * FROM posts WHERE id = ?;
?
の部分には、params[:id]
の値が入ります。
params[:id]とは何か
params[:id]
というのは、URLの末尾の数字部分を表しています。
たとえば http://127.0.0.1:3000/posts/1
というURLにアクセスすると、Railsは「1」をparams[:id]
として認識します。そして、この「1」という値を使って、IDが1の投稿データを取得します。
ID とは、データが作成された順に割り振られる連番のことです。マイナンバーのような、識別番号と考えてください。
showアクションで取得した@post
の情報は、show.html.erb
に渡され、そこでタイトルや本文などの詳細情報が表示されます。
インスタンス変数の役割を理解する
ここまで見てきたように、コントローラのアクション内でインスタンス変数(@で始まる変数)を定義すると、それが対応するビューに自動的に受け渡されます。
例えば、indexアクションで定義した@posts
はindex.html.erb
で使え、showアクションで定義した@post
はshow.html.erb
で使えます。
この仕組みにより、コントローラでデータベースから取得したデータを、ビューで表示することができるのです。
インスタンス変数を使わない(@をつけない)ローカル変数の場合は、アクション内でしか使えず、ビューには渡されません。つまり、@ は「ビューに渡したい変数」を意味すると考えてください。
ビューでのデータの表示方法
@posts
や@post
がビューに渡されたあと、どのように表示されるのでしょうか?
例えば、app/views/posts/index.html.erb
には、以下のようなコードが含まれているかもしれません。
<h1>投稿一覧</h1>
<% @posts.each do |post| %>
<div>
<h2><%= post.title %></h2>
<p><%= post.body %></p>
<p><%= link_to "詳細", post_path(post) %></p>
</div>
<% end %>
このコードでは、@posts
から取得したすべての投稿に対して.each
メソッドを使ってループを行い、各投稿のタイトルと本文、そして詳細ページへのリンクを表示しています。
同様に、app/views/posts/show.html.erb
には、以下のようなコードが含まれているかもしれません。
<h1><%= @post.title %></h1>
<p><%= @post.body %></p>
<div>
<%= link_to "編集", edit_post_path(@post) %>
<%= link_to "削除", post_path(@post), method: :delete, data: { confirm: "本当に削除しますか?" } %>
<%= link_to "一覧に戻る", posts_path %>
</div>
このコードでは、@post
から取得した1つの投稿のタイトルと本文を表示し、編集・削除のリンクと一覧に戻るリンクを表示しています。
まとめ
本章では、Railsのコントローラにおけるindex, showアクションの役割と動作原理について学びました。
- indexアクションは、モデルのすべてのレコードを取得して一覧表示するためのもの
- showアクションは、特定のIDを持つレコードを1つだけ取得して詳細表示するためのもの
- コントローラでインスタンス変数(@で始まる変数)を定義すると、対応するビューでその変数を使える
Post.all
ですべてのレコードを取得、Post.find(params[:id])
で特定のレコードを取得できるparams[:id]
はURLの末尾の数字部分から取得される
これらの基本的な概念は、Railsアプリケーション開発の土台となるものです。次の章では、new, createアクションについてさらに学んでいきましょう。