今回の学習
3-1. ターミナル(コマンドプロンプト)の使い方
3-2. Ruby on Rails について
3-3. データベースの構造を理解しよう
3-4. MVCの基本を学ぼう
3-5. ページ遷移を実装しよう
3-6. Railsの構成について
3-7. モデルとマイグレーションについて
3-8. 投稿ページを表示しよう
3-9. ツイートを投稿しよう
3-10. 投稿機能おさらい前編 -投稿ページにフォームを表示する
3-11. 投稿機能解説おさらい後編 -フォームから送信された情報を保存する
3-12. 一覧ページを表示しよう
3-13. 詳細ページを表示しよう
3-14. ツイートを編集しよう
3-15. ツイートを削除しよう
はじめに
今回はツイートの詳細ページを作ります。
一覧ページに並んでいるツイートをクリックすると、そのツイートに関する詳細が見られるページというイメージです。
概要
実装は、「ルーティング、アクション、ビュー」の順に行います。
tweet#show
アクションへのルーティングを実装したら、
アクション内でパス内のid
情報を使って、対応するid
のツイート情報をデータベースから取得します。
次にビューの方で取得したツイートの各種情報を表示します。
また、一覧ページから詳細ページに遷移できるように、リンクも用意しなければなりません。
これはlink_to
を使って実装します。
それでは作っていきます。
▼▼▼実装&解説動画
実装
ルーティング
Rails.application.routes.draw do
#割愛
get 'tweets/:id' => 'tweets#show',as: 'tweet'
end
as: ~
という見慣れない表現が出てきました。
詳細な説明は割愛しますが、これはtweets#show
に遷移するためのパスをtweet
に明示的に指定するための記述です。
今は「ヘぇ〜、そうなんだ〜」くらいに思ってくれれば大丈夫です。
できたルーティングを確認します。
$ rails routes
tweets#show
というアクションを作りました。
tweets#show
はGET
メソッドでアクセスしているので、単にページを表示するだけのアクションです。
パス(URI Pattern
)をみてみると、tweets/:id
という書き方になっています。
パスの中に:
(コロン)がついてるとき、その文字列は変数
として認識されます。
今回の場合だとtweets/:id
となっているため:id
が変数となります。
これにより、:id
の部分に入った文字を、アクションの中でparams[:id]
と入力することによって受け取れるようになります。
例えばtweets/123
というページにアクセスすると、params[:id]
で123
を受け取れます。
今はイマイチ理解できなくても、コードを書きながら手に馴染ませて理解を深めていきましょう。
…
Railsでは、あるアクションで定義された変数を別のアクションで使うことはできません。アクションはそれぞれ互いに無関係に実行されます。
tweets#show
アクションでも、データベースからツイートのデータを取ってくる必要があります。
続いてtweets#show
アクションを実装します。
詳細ページ表示 - tweets#show
コントローラー - tweets_controller.rb
以下のようにshowアクションを定義します。privateより上側に書きましょう。
class TweetsController < ApplicationController
def index
@tweets = Tweet.all
end
def new
@tweet = Tweet.new
end
def create
tweet = Tweet.new(tweet_params)
if tweet.save
redirect_to :action => "index"
else
redirect_to :action => "new"
end
end
# 追記ここから
def show
@tweet = Tweet.find(params[:id])
end
# ここまで
private
def tweet_params
params.require(:tweet).permit(:body)
end
end
@tweet
という変数に、送られてきたid
のツイートの情報を代入しています。
ビュー - show.html.erb
さきほど用意した@tweet
をつかって詳細ページを表示します。
まずはapp/views/tweetsの階層にshow.html.erb
ファイルを作成してください。
続いて以下のようなコードを記入してください。
<h1>GeekTwitter</h1>
<h3>Tweet詳細</h3>
<div class="tweet">
<p><%= @tweet.body %></p>
<p><%= @tweet.created_at %></p>
</div>
<%= link_to "Tweet一覧に戻る", tweets_path %>
ツイートの内容と作成日時を表示しています。
一覧ページ表示 - tweets#index
コントローラーの中身は変更しませんが、
詳細ページへのリンクを表示するためにビューファイルを変更します。
<%= link_to "詳細へ", tweet_path(t.id) %>
の一行を
<% @tweets.each do |t| %>
~~ <% end %>
の間に追加します。
ビュー - index.html.erb
<h1>GeekTwitter</h1>
<h3>Tweet一覧</h3>
<%= link_to "新規投稿へ", tweets_new_path %>
<div class="tweets-container">
<% @tweets.each do |t| %>
<div class="tweet">
<%= t.body %>
<%= t.created_at %>
#追記始め
<%= link_to "詳細へ", tweet_path(t.id) %>
#追記終わり
</div>
<% end %>
</div>
確認
$ rails s
一覧ページ(localhost:3000
)にアクセスみましょう!
前回ツイートを投稿していたら、その詳細ページへのリンクが追加されているはずです。
それをクリックすると…
以上のようになったでしょうか?
解説
詳細ページ表示 - tweets#show
コントローラー - tweets_controller.rb
class TweetsController < ApplicationController
# 割愛
def show
@tweet = Tweet.find(params[:id])
end
private
# 割愛
end
tweets#show
アクションでは、まず一覧ページから送られてきたid
に対応するツイートをデータベースから取得します。
ここで各ツイートはそのツイート固有の番号がid
カラムに保存されています。
実際私たちはtweetsテーブルを作成する際にidカラムは作成していませんでしたが、このカラムはRailsがデフォルトで作成してくれ、新しいツイートが保存される毎に新しい番号をツイートに割り振ってくれています。
ツイートをid
で検索して取得するには、Railでもともと定義されているfind
メソッドを使います。
以下はid
が1のツイートの情報を取得するコードです。
Tweet.find(1)
今回は、検索するツイートのid
はparams[:id]
に入っている数字を使うので、以下のようになります。
Tweet.find(params[:id])
まとめると、パスに含まれる:id
をparams[:id]
で受け取り、そのid
に対応するツイートの情報を探し、それをビューファイルの中で扱えるように@tweet
に代入しています。
idが2のツイートをデータベースのtweetsテーブルから持ってきています。
一覧ページ表示 - tweets#index
<%= link_to "詳細へ", tweet_path(t.id) %>
link_to
を使って一覧ページから詳細ページに遷移できるようにしています。
これまでのlink_to
と違うところは、〇〇_path
の後に(t.id)
があることです。
tweet_path(t.id)
と書くことで、:id
にt.id
を埋め込んだtweet_path
を作成してくれます。
このおかげでshowアクションのparams[:id]
に必要なidを送ることができます。
ソースコードの確認
最後にGithubでソースコードを確認しましょう! エラーが出てる方は、下記のURLにアクセスしてソースコードに間違いがないか確認しよう! 確認する場合は下のGithubをクリック!クイズ
①ツイートをidで検索して取得するには、Railでもともと定義されている ? メソッドを用いる
答え
find②詳細に飛ぶためのリンクを作るコードは?
答え
<%= link_to "詳細へ", tweet_path(t.id) %>おわりに
以上で詳細ページの実装は完了です!お疲れ様でした!!!
記録フォームの送信
ここまでお疲れ様です!
最後にみなさんが本記事をいつ終えたか記録すること、また本記事をさらにいいものにするために以下のフォームに記入いただけると嬉しいです!