ここでは、マイページを作成する。
マイページは、ユーザー1人についての詳細画面として実装することが多い。
PicTweetでは、あるユーザーのツイート一覧を表示できるようにする。
マイページを作成する
現在、ツイートの一覧画面には全ユーザーのツイートが表示されている。
そこで、一覧画面とは別に、現在ログイン中のユーザーの投稿のみが表示されているマイページを作成する。
作業内容
- マイページのルーティングを記述する
- コントローラとアクションを作成する
- マイページ用のビューファイルを作成する
- マイページへのリンクを作成する
1.マイページのルーティングを記述する
新しくページを作成する場合、まずはルーティングを設定する。
マイページへのパスは、usersテーブルでのidが1のユーザーでは/users/1、idが99のユーザーでは/users/99となるようにルーティングを設定する。
マイページのパスは他のページと違って、ユーザーごとにパスが異なる。
その場合、通常とは多少異なるルーティングの記述方法を使う。
マイページを表示する際にはusersコントローラのshowアクションを動かす。
showアクションへのルーティングは、以下のように書く。
【例】
config/routes.rb
Rails.application.routes.draw do get '/コントローラ名/:id' => 'コントローラ名#show' end
:idの部分には表示するユーザーページのユーザーのidが入る。
config/routes.rbを以下のように編集する。
config/routes.rb
Rails.application.routes.draw do devise_for :users root 'tweets#index' get 'tweets' => 'tweets#index' get 'tweets/new' => 'tweets#new' post 'tweets' => 'tweets#create' get 'users/:id' => 'users#show' #Mypageへのルーティング end
このようにルーティングを定義することによって、パスの一部をコントローラにパラメーターというハッシュ形式で値を送る事ができる。
これはparamsというメソッドを使用することで取得することができる。
コントローラ内でparams[:id]と記述することにすれば/users/:idの:id部分の情報を使用することができる。
後ほどparamsの中身を見ていく。
2.コントローラとアクションを作成する
先ほど、マイページを表示するためにusersコントローラのshowアクションを動かすルーティングを設定した。
続いてusersコントローラを作成し、showアクションを定義していく。
whereメソッド
whereメソッドはActiveRecordメソッドのうちの一つです。モデル.where(条件)のように引数部分に条件を指定することで、テーブル内の条件に一致したレコードのインスタンスを配列型で取得できる。
また、whereメソッドを連続して記述することによって、複数の条件に一致したレコードを取得することもできる。
【例】
コンソール
[1] pry(main)> Tweet.where('id < 3') => [#<Tweet id: 1, image: "test1.jpg", text: "いい景色だ。", created_at: "2014-12-06 00:00:00", updated_at: "2014-12-06 00:00:00", user_id: 1>,#<Tweet id: 2, image: "test2.jpg", text: "Thank you!", created_at: "2014-12-07 00:00:00", updated_at: "2014-12-07 00:00:00", user_id: 2>] # idが3未満のtweetsテーブルのインスタンスを配列で取得 [2] pry(main)> Tweet.where('id < 3').where(user_id: 1) => [#<Tweet id: 1, image: "test1.jpg", text: "いい景色だ。", created_at: "2014-12-06 00:00:00", updated_at: "2014-12-06 00:00:00", user_id: 1>] # idが3未満かつuser_idが1のtweetsテーブルのインスタンスを配列で取得
以下の指示に従い、users_controllerを作成する
ターミナル
$ rails g controller users # users_controllerと関連するファイルを作成
新規作成されるファイル
- app/controllers/users_controller.rb
- test/controllers/users_controller_test.rb
- app/helpers/users_helper.rb
- test/helpers/users_helper_test.rb
- app/assets/javascripts/users.coffee
- app/assets/stylesheets/users.scss
続いて、作成したusers_controllerにshowアクションを定義する。
showアクションで表示するのはユーザーのマイページだが、マイページに必要な情報はニックネームとログイン中のユーザーのツイートの2つである。
そこで、showアクションにはユーザーページを表示する際に必要な情報をビューに受け渡す処理を記述する。
ビューに情報を受け渡す際にはインスタンス変数(@付きの変数)をコントローラのアクション内で定義する。
今回の場合、必要な情報はニックネームとログイン中のユーザーのツイートの2つである。
それぞれを@nicknameと@tweetsという変数に定義する。
問題1:マイページに表示したい情報をshowアクションに定義しましょう
作業ファイル:app/controllers/users_controller
ヒント:@tweetsを定義する際はActiveRecordメソッドのwhereを使用します。
1 2 3 4 5 6 7 8 |
class UsersController < ApplicationController
def show
@nickname = 現在ログインしているユーザーのニックネーム
@tweets = 現在ログインしているユーザーが投稿したツイート
end
end
|
【 問題1の解答を確認する 】
3.マイページ用のビューファイルを作成する
usersコントローラにshowアクションを定義することができたため、アクションに対応するビューファイルを作成していく。
以下の指示に従い、app/views/users/show.html.erbを作成する
①ファイルの新規作成
先ほどusers_controllerを作成した際にapp/views/usersディレクトリが作成されているので、その中にshow.html.erbというファイルを作成する。
新規作成されるファイル
app/views/users/show.html.erb
②ファイルの編集
作成したファイルを、以下のように編集しましょう。
app/views/users/show.html.erb
<div class="contents row"> <p><%= @nickname %>さんの投稿一覧</p> <% @tweets.each do |tweet| %> <div class="content_post" style="background-image: url(<%= tweet.image %>);"> <%= simple_format(tweet.text) %> <span class="name"><%= tweet.name %></span> </div> <% end %> </div>
4.マイページへのリンクを作成する
マイページへはPicTweetのページ上部から遷移できるように実装する。
本項の1.マイページのルーティングを記述するで実装した通り、マイページへのパスは/users/ログイン中のユーザーのidである。
こちらをどう記述するかが鍵になる。
問題2:マイページへのリンクを作成しましょう
作業ファイル:app/views/layouts/application.html.erb
ヒント:マイページのパスは「/users/ログイン中のユーザーのid」となっています。そのため、ビューファイルもログイン中のユーザーによってリンクが変化するようにRubyタグを使って記述を行います。
【例】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<header class="header">
<div class="header__bar row">
<h1 class="grid-6"><a href="/">PicTweet</a></h1>
<% if user_signed_in? %>
<div class="user_nav grid-6">
<span>ログイン中のユーザーのニックネームを記述
<ul class="user__info">
<li>
<a href="/users/ログイン中のユーザーのid">マイページ</a>
<%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
</li>
</ul>
</span>
<a class="post" href="/tweets/new">投稿する</a>
</div>
<% else %>
<div class="grid-6">
<%= link_to "ログイン", new_user_session_path, class: 'post' %>
<%= link_to "新規登録", new_user_registration_path, class: 'post' %>
</div>
<% end %>
</div>
</header>
|
【 問題2の解答を確認する 】
トップページに下記のアドレスを追加してマイページが作成されているか確認しましょう
「トップページアドレス/users/ログイン中のユーザーのid」 にアクセスしてマイページを開いてみる。
最後にルーティングを設定したところで一度触れたパラメーターについて見ていく。
paramsの中を確認するにはbinding.pryを使用する。
/app/controllers/users_controller.rbのshowアクションを以下のように編集する
users_controller.rb
class UsersController < ApplicationController def show binding.pry @nickname = current_user.nickname @tweets = Tweet.where(user_id: current_user.id) end end
編集したら、「トップページアドレス/users/ログイン中のユーザーのid」 にアクセスする。
ログインしているユーザーのID番号が1ならば、トップページアドレス/users/1 である。
ここでの「ログインしているユーザーのid」には、現在ログインしているユーザーのidを入力する。
phpMyAdminのusersテーブルで確認する。
するとサーバーが停止するので、ターミナルを確認する。
ターミナル
2: def show => 3: binding.pry 4: @nickname = current_user.nickname 5: @tweets = current_user.tweets 6: end
この状態で、paramsと入力する。
ターミナル
[1] pry(<UsersController>)> params => {"controller"=>"users", "action"=>"show", "id"=>"1"}
paramsというハッシュの中に"id" => "1"というキーとバリューが追加されているのが確認できる。
このparamsがコントローラに送られてくるのでコントローラ内でparams[:id]とすることでユーザーのidを取得することができる。
なぜ自動的にparams の中にuserのidが入るのかというとルーティングで設定してあるからである。
もう一度routes.rbを確認してみる。
config/routes.rb
Rails.application.routes.draw do devise_for :users root 'tweets#index' get 'tweets' => 'tweets#index' get 'tweets/new' => 'tweets#new' post 'tweets' => 'tweets#create' get 'users/:id' => 'users#show' end
7行目で「get 'users/:id' => 'users#show'」と設定してあるため、「user/1」というパスが送られると、paramsの中に「id」としてuserのidである「1」が入り、userコントローラーのshowアクションでuserのidをparamsから取り出せるという流れになる。
また、ルーティングで:idの部分の名前を変更するとparams内のキーの名前も変更される。
【例】:idの部分の名前を:user_idのように変更すると、以下のようにキーがuser_idになります。
ターミナル
[1] pry(<UsersController>)> params => {"controller"=>"users", "action"=>"show", "user_id"=>"1"}
binding.pryを解除する
このままだと次にアプリを動かした時も止まってしまいますので、削除しておく。
①users_controller.rbに記述したbinding.pryを削除する
②ターミナルで「exit」と入力してbinding.pryを解除する。