さらなる高みへ -higher ground -

プログラミング学習の定着を狙いとしたアウトプット(独り言)をしてみるブログ

マイページを作成する

ここでは、マイページを作成する。
マイページは、ユーザー1人についての詳細画面として実装することが多い。
PicTweetでは、あるユーザーのツイート一覧を表示できるようにする。

マイページを作成する

現在、ツイートの一覧画面には全ユーザーのツイートが表示されている。
そこで、一覧画面とは別に、現在ログイン中のユーザーの投稿のみが表示されているマイページを作成する。

作業内容

  1. マイページのルーティングを記述する
  2. コントローラとアクションを作成する
  3. マイページ用のビューファイルを作成する
  4. マイページへのリンクを作成する

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を使用します。
users_controller.rb
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というファイルを作成する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//13a69361534d550ba19cd5c27926bbfd.gif

新規作成されるファイル

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タグを使って記述を行います。
【例】
app/views/layouts/application.html.erb
 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」 にアクセスしてマイページを開いてみる。

https://tech-master.s3.amazonaws.com/uploads/curriculums//d13fb3deca463db5817807ee0e1eb761.png

 

最後にルーティングを設定したところで一度触れたパラメーターについて見ていく。
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を解除する。

要点チェック