LoginSignup
0
0

More than 3 years have passed since last update.

Railsチュートリアル 第7章 ユーザー登録 - ユーザーを表示する

Posted at

静的なページ、コントローラ、モデルと来て、ここからはいよいよ真に動的なページの作成に取り掛かっていきます。その記念すべき第一弾となるのが、今回実装するプロフィールページです。

今節においては、以下の要素が表示できるプロフィールページを作成していきます。

  • ユーザーの名前
  • プロフィール写真

プロフィールページの最終的な完成像としては、以下の要素が表示できることを目指します。

  • プロフィール写真
  • 基本ユーザーデータ
  • マイクロポストの一覧

デバッグとRails環境

Webサイトのレイアウトにデバッグ情報を追加する

デバッグ情報の追加は、サンプルアプリケーションに動的なページを追加する前段階となります。使用するのは以下のリソースです。

  • debugメソッド
  • params変数
app/views/layouts/application.html.erb
  <!DOCTYPE html>
  <html>
    ...略
    <body>
      <%= render 'layouts/header' %>
      <div class="container">
        <%= yield %>
        <%= render 'layouts/footer' %>
+       <%= debug(params) if Rails.env.development? %>
      </div>
    </body>
  </html>

以上のコードを追加することにより、開発環境(development)において、各プロフィールページにデバッグ用の情報が表示されるようになります。

特筆すべきは以下のRubyコードです。

if Rails.env.development?

これは、開発環境(development)でのみtrueになる条件式です。

<%= debug(params) if Rails.env.development? %>

ゆえに、上記の埋め込みRubyは以下の動作をすることになります。

  • 本番環境やテストには挿入されない
  • 開発環境1でのみ、各プロフィールページにデバッグ用の情報を表示する

デバッグ出力の表示を整形するために、カスタムスタイルシートに追加の記述を行う

app/assets/stylesheets/custom.scss
    @import "bootstrap-sprockets";
    @import "bootstrap";

    /* mixins, variables, etc. */

    $gray-medium-light: #eaeaea;

+   @mixin box_sizing {
+       -moz-box-sizing: border-box;
+       -webkit-box-sizing: border-box;
+       box-sizing: border-box;
+   }

    ..略
+
+   /* miscellaneous */
+   .debug_dump {
+       clear: both;
+       float: left;
+       width: 100%;
+       margin-top: 45px;
+       @include box_sizing;
+   }

上記は、デバッグ出力をきれいに整形するためにapp/assets/stylesheets/custom.scssに追加で記述するコードです。「Sassのミックスイン機能を使用している(@mixin box_sizing以下の記述)」というのがポイントです。

結果として、デバッグ環境のHomeページをWebブラウザでレンダリングした結果は、現在のところは以下のスクリーンショットのような出力となります。

スクリーンショット 2019-10-13 22.41.37.png

Sassのミックスイン機能

Sassのミックスイン機能を使うことにより、CSSルールのグループをパッケージ化して複数の要素に適用することができます。

例えば、例1のコードは例2のように展開されます。

例1
@mixin box_sizing {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

.debug_dump {
    /* ...略 */
    @include box_sizing;
}
例2
.debug_dump {
    /* ...略 */
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

デバッグ出力の内容

演習 - デバッグとRails環境

1. ブラウザから/aboutにアクセスし、デバッグ情報が表示されていることを確認してください。このページを表示するとき、どのコントローラとアクションが使われていたでしょうか?paramsの内容から確認してみましょう。

paramsの内容は以下のとおりです。

--- !ruby/object:ActionController::Parameters
parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  controller: static_pages
  action: about
permitted: false
  • コントローラはstatic_pages
  • アクションはabout

以上であることがわかります。

2. Railsコンソールを開き、データベースから最初のユーザー情報を取得し、変数userに格納してください。その後puts user.attributes.to_yamlを実行すると何が表示されますか?

>> user = User.find(1)
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2019-10-13 06:43:53", updated_at: "2019-10-13 06:43:53", password_digest: "$2a$10$rb26ZPyWkUh8T/cWML/OM.VhDiuJaii877zf3SvsfN5...">

>> puts user.attributes.to_yaml
---
id: 1
name: Michael Hartl
email: mhartl@example.com
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2019-10-13 06:43:53.935111000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2019-10-13 06:43:53.935111000 Z
  zone: *2
  time: *3
password_digest: "$2a$10$rb26ZPyWkUh8T/cWML/OM.VhDiuJaii877zf3SvsfN56IOU/ibHei"
=> nil

2.2. 2.1.で表示された結果と、yメソッドを使ったy user.attributesの実行結果を比較してみましょう。

>> y user.attributes
---
id: 1
name: Michael Hartl
email: mhartl@example.com
created_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &1 2019-10-13 06:43:53.935111000 Z
  zone: &2 !ruby/object:ActiveSupport::TimeZone
    name: Etc/UTC
  time: *1
updated_at: !ruby/object:ActiveSupport::TimeWithZone
  utc: &3 2019-10-13 06:43:53.935111000 Z
  zone: *2
  time: *3
password_digest: "$2a$10$rb26ZPyWkUh8T/cWML/OM.VhDiuJaii877zf3SvsfN56IOU/ibHei"
=> nil

puts user.attributes.to_yamlの結果とy user.attributesの結果は、特に変わりないように見えます。いずれも戻り値はnilであり、副作用として、ユーザーオブジェクトの内容をyamlとしてパースしたものが標準出力に出力されています。

Usersリソース

RDB上に一人分のユーザー情報が登録されていることを確認する

ユーザープロフィールページを作成するには、RDB上にユーザーが登録されている必要があります。第6章の時点で「Railsコンソールを使ってRDB上にユーザーを登録する」という操作を行ったのは、実はそのためだったのです。

# rails console

>> User.count
   (2.1ms)  SELECT COUNT(*) FROM "users"
=> 1
>> User.first
  User Load (0.4ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2019-10-13 06:43:53", updated_at: "2019-10-13 06:43:53", password_digest: "$2a$10$rb26ZPyWkUh8T/cWML/OM.VhDiuJaii877zf3SvsfN5...">

ここでは、「RDB上に既に1個のユーザー情報が存在しており、そのユーザーのIDは1である」というのがポイントです。

RESTアーキテクチャと、ユーザー情報の表示の実装計画

Railsアプリケーションにおいては、RESTアーキテクチャの習慣に従い、「データの作成・表示・更新・削除2をリソースに割り付ける」という手法を取ることが好まれます。HTTP標準のリクエストとCRUDの各操作は、以下のように対応付けられるのが一般的です。

HTTP標準のリクエスト CRUDの各操作
POST Create
GET Read
PATCH Update
DELETE Delete

RESTの原則に従う場合、リソースへの参照は、リソース名とユニークなIDを使うのが一般的です。例えば、id=1のユーザーの情報を表示する場合、対応する操作は、「/users/1というURLに対してGETリクエストを発行する」という操作になります。

というわけで、RESTの原則に従うならば、ユーザー情報に対するCRUD機能のコントローラを実装するためには、POST・GET・PATCH・DELETEの各リクエストをコントローラのアクションに割り付けていくというのが基本方針となります。

showアクション、その他RESTfulなUsersリソースに対するルーティングが利用できるようにする

Railsのコントローラで定義されたアクションは7つあり、そのうちのshowアクションは、暗黙的にGETリクエストと対応付けられています。RailsのREST機能が有効になっていれば、GETリクエストは自動的にshowアクションとして扱われるのです。

ただ、現時点で/users/1にアクセスするとエラーになります。/users/1へのGETリクエストに対するルーティングが定義されていないためです。

Started GET "/users/1" for 172.17.0.1 at 2019-10-13 15:37:30 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255

ActionController::RoutingError (No route matches [GET] "/users/1"):
...略

というわけで、/users/1へのGETリクエストに対するルーティングを定義しましょう。修正するファイルは、/config/routes.rbです。

/config/routes.rb
  Rails.application.routes.draw do
    get 'users/new'

    root 'static_pages#home'
    get '/help', to: 'static_pages#help'
    get '/about', to: 'static_pages#about'
    get '/contact', to: 'static_pages#contact'
    get '/signup', to: 'users#new'
+   resources :users
  end

/config/routes.rbresources :usersという記述を加えると、/users/1に限らず、RESTfulなUsersリソースで必要となるHTTPリクエスト(POST・GET・PATCH・DELETE)と対応するURLの組すべてに対するルーティングが定義されます。実際に定義されるルーティングの一覧表は、Railsチュートリアルの表 7.1の通りになります。

次になすべきことは

ただ、ルーティングが定義されたとしても、まだルーティング先のアクションがコントローラで定義されていないですし、ルーティング先のページが存在するわけでもありません。/users/1にアクセスすると、やはりエラーになります。

Started GET "/users/1" for 172.17.0.1 at 2019-10-13 15:50:14 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255

AbstractController::ActionNotFound (The action 'show' could not be found for UsersController):
...略

エラーにはなりますが、その内容が変化していますね。「ルーティングが見つからない」というのではなく、「コントローラでshowアクションが定義されていない」という内容になりました。

この状態からshowアクションが正しく動作するようにするためには、以下の2つの実装が必要になります。

  • Usersリソースに対するshowビューの実装
  • Usersコントローラに対するshowアクションの実装

Usersリソースに対するshowビューの実装

Railsにおいて、「Usersリソースに対するshowビュー」を指すファイルは、app/views/users/show.html.erbとなります。しかしながら、現時点で当該ファイルは存在しません。まずはapp/views/users/show.html.erbを新規作成するのが最初のプロセスとなります。

app/views/users/show.html.erbの最初の内容は、以下の通りです。「埋め込みRubyにより、ユーザー名とメールアドレスを表示する」という内容になります。

`app/views/users/show.html.erb`
<%= @user.name %>, <%= @user.email %>

Usersコントローラに対するshowアクションの実装

Usersリソースに対するshowビューが正常に動作するためには、Usersコントローラにshowアクションに、対応する@user変数が実装されている必要があります。編集するファイルはapp/controllers/users_controller.rbです。以下の内容を追加します。

app/controllers/users_controller.rb
  class UsersController < ApplicationController
+
+   def show
+     @user = User.find(params[:id])
+   end
+
    def new
    end
  end

ポイントは以下です。

  • ユーザーのid読み出しには、paramsメソッドを用いている
    • Usersコントローラが正常なリクエストを受け取ると、例えばid=1の場合、@user = User.find(1)という処理を実行することに成る
  • param[:id]の戻り値は文字列型の"1"だが、findメソッドでは自動的に整数型に変換される

ここまでの変更を反映した時点で、/users/1が完全に動作するようになります。以下にスクリーンショットを掲載します。

スクリーンショット 2019-10-14 20.59.12.png

--- !ruby/object:ActionController::Parameters
parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  controller: users
  action: show
  id: '1'

上記のとおり、デバッグ情報からparam[:id]の値を確認できるようになりました。id: '1'というのは、/users/:idというURLから取得された値です。これにより、User.find(params[:id])User.find(1)と解釈される一連の仕組みが確立されました。

演習 - Usersリソース

1. 埋め込みRubyを使って、マジックカラム (created_atとupdated_at) の値をshowページに表示してみましょう (リスト 7.4)。

変更対象のファイルはapp/views/users/show.html.erbです。以下のように変更してみます。

app/views/users/show.html.erb
  <%= @user.name %>, <%= @user.email %>
+ Created: <%= @user.created_at %>, Updated: <%= @user.updated_at %>

結果は以下のようになりました。

スクリーンショット 2019-10-14 21.11.57.png

2. 埋め込みRubyを使って、Time.nowの結果をshowページに表示してみましょう。ページを更新すると、その結果はどう変わっていますか? 確認してみてください。

app/views/users/show.html.erb
  <%= @user.name %>, <%= @user.email %>
  Created: <%= @user.created_at %>, Updated: <%= @user.updated_at %>
+ 現在の時刻: <%= Time.now %>

スクリーンショット 2019-10-14 22.12.02.png

スクリーンショット 2019-10-14 22.12.09.png

「現在の時刻:」以降の表示内容が、Webページを更新するたびに変わっていきます。

debuggerメソッド

byebug gemは既にインストールされている

最初の環境構築の段階で、開発環境(Development)向けにbyebugというGemをセットアップしました。

Gemfile
source 'https://rubygems.org'
...略

group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug',  '9.0.6', platform: :mri
end

...略

このbyebug gemが提供するdebuggerメソッドにより、今まで用いてきたdebugメソッドよりさらに直接的にデバッグを行うことが可能です。

実際にdebuggerメソッドを使ってみる

まずは、実際にdebuggerメソッドをRailsアプリケーションに差し込んでみましょう。

app/controllers/users_controller.rb
  class UsersController < ApplicationController

    def show
      @user = User.find(params[:id])
+     debugger
    end

    def new
    end
  end

この状態で/users/1というページを表示すると、rails serverを立ち上げたシェルに、以下のようなプロンプトが出てきます。

(byebug)

このプロンプトでは、Railsコンソールのようにコマンドを実行することができ、アプリケーションのdebuggerが呼び出された瞬間の状態を確認することが可能です。

(byebug) @user.name
"Michael Hartl"
(byebug) @user.email
"mhartl@example.com"
(byebug) params[:id]
"1"

プロンプトを抜けるには、Ctrl-Dを押します。また、デバッグが終わったらdebugger行は削除する必要があります。プロンプトが出ている状態だと、アプリケーションの実行が中断されるからです。

app/controllers/users_controller.rb
  class UsersController < ApplicationController

    def show
      @user = User.find(params[:id])
-     debugger
    end

    def new
    end
  end

debuggerメソッドを使う際のポイント

  • Railsアプリケーション内でよくわからない挙動があったら、躊躇なくdebuggerコードを挿し込んで調べてみる
  • debuggerコードは、トラブルが起こっていそうなコードのできるだけ近くに差し込む

byebug gemによるシステム状態の調査は、アプリケーションの動作の追跡・デバッグに際して非常に強力なツールとなります。

演習 - debuggerメソッド

1. showアクションの中にdebuggerを差し込み (リスト 7.6)、ブラウザから /users/1 にアクセスしてみましょう。その後コンソールに移り、putsメソッドを使ってparamsハッシュの中身をYAML形式で表示してみましょう。

app/controllers/users_controller.rb
  class UsersController < ApplicationController

    def show
      @user = User.find(params[:id])
+     debugger
    end

    def new
    end
  end
(byebug) puts params.to_yaml
--- !ruby/object:ActionController::Parameters
parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  controller: users
  action: show
  id: '1'
permitted: false
nil

2. newアクションの中にdebuggerを差し込み、/users/new にアクセスしてみましょう。@userの内容はどのようになっているでしょうか? 確認してみてください。

app/controllers/users_controller.rb
  class UsersController < ApplicationController

    def show
      @user = User.find(params[:id])
    end

    def new
+     debugger
    end
  end

以下の通り、@userputsしても、型もアドレスも表示されません。

(byebug) puts @user

nil

一方で、showアクションにdebuggerメソッドを挿入した状態で@userputsした結果は以下のようになります。型とアドレスが表示されていますね。

(byebug) puts @user
#<User:0x00007f34780e2de8>
nil

Gravater画像とサイドバー

Gravatarとは

Globally Recognized AVATARの略です。プロフィール写真をアップロードして、指定のメールアドレスと紐付ける事ができるサービスです。Gravatarを利用することにより、プロフィール写真の運用について、以下の利便を実現することができます。

  • プロフィール写真をアップロードする面倒な作業から解放される
  • 写真が欠けるトラブルから解放される
  • 画像の置き場所の悩みが解決される

Gravatar画像を利用できるサービスとしては、例えば以下のものが挙げられます。

  • Github
  • Slack
  • Qiita

RailsアプリケーションでもGravatarのプロフィール画像を利用することができます。

gravatar_forヘルパーメソッドを呼び出すようにする

現在作成中のアプリケーションでは、「gravatar_forというヘルパーメソッドを使ってGravatarの画像を利用できるようにする」とう方針を取ることとします。

まず、ユーザー表示ビューでgravatar_forヘルパーメソッドを使用するようにコードを書き換えていきましょう。

app/views/users/show.html.erb
- <%= @user.name %>, <%= @user.email %>
+ <% provide(:title, @user.name) %>
+ <h1>
+   <%= gravatar_for @user %>
+   <%= @user.name %>
+ </h1>

「デフォルトでは、ヘルパーファイルで定義されているメソッドは、自動的にすべてのビューで利用できる」という言及は注目に値します。

なお、今回は、利便性を考え「gravatar_forをUsersコントローラに関連付けられているヘルパーファイルに置く」という方針を取ります。

文字列に対するMD5ハッシュを得る

GravatarのURLは、ユーザーのメールアドレスをMD5というハッシュ関数でハッシュ化したものを用いています。そのため、Gravatarを利用するシステムの側でもMD5ハッシュを得る処理を実装する必要があります。

Rubyでは、Digestライブラリのhexdigestメソッドを用いることにより、文字列に対するMD5ハッシュを得ることができます。以下のRailsコンソールの処理結果がその例です。

>> email = "MHARTL@example.COM"
=> "MHARTL@example.COM"
>> Digest::MD5::hexdigest(email.downcase)
=> "1fda4469bcbec3badf5418269ffc5968"

以下の事柄は重要です。

  • RubyのStringクラスのdowncaseメソッドを用いて、hexdigestの引数を小文字に変換している
    • 現在作成中のアプリケーションではメールアドレスの大文字小文字を区別しない一方、MD5ハッシュを生成するための入力では大文字小文字を区別するため
  • 現在作成中のアプリケーションを前提とした場合、実際のところ、MD5ハッシュを生成する時点でメールアドレスを小文字に変換する処理を入れるのは冗長である
  • gravatar_forメソッドが単独で呼び出される可能性を考え、MD5ハッシュを生成する時点で小文字に変換する処理を入れている

gravatar_forヘルパーメソッドを定義する

MD5ハッシュを得る処理の内容がわかったので、実際に「Railsアプリケーションの登録メールアドレスを元に、Gravatarからプロフィール画像を得る」という処理を実装していきましょう。

app/helpers/users_helper.rb
  module UsersHelper
+   def gravatar_for(user)
+     gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
+     gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
+     image_tag(gravatar_url, alt: user.name, class: "gravatar")
+   end
  end

image_tagメソッドのオプションハッシュには、alt属性とclass属性を与えています。それぞれ以下の意味になります。

  • alt属性の内容は、画像が表示できない場合の代替テキストを意味する
  • class属性の内容により、HTMLの各要素をグループ化し、主にCSSで使うことができる

上記のコードを追加しても、プロフィール画像が表示されない場合

スクリーンショット 2019-10-16 7.13.03.png

ここまでのコードを追加して、改めて/users/1をブラウザで表示した結果です。…プロフィール画像が表示されていません。なぜでしょうか。

teratailに答えがありました。当方の環境でも、確かにimg要素に対してdisplay: noneという内容のCSSコードが存在します(下掲スクリーンショット)。

スクリーンショット 2019-10-16 7.16.24.png

原因は何かというと、第5章の演習で追加したコード(リスト 5.11)のようです。app/assets/stylesheets/custom.scssの対応する部分のコードを削除します。

app/assets/stylesheets/custom.scss
    @import "bootstrap-sprockets";
    @import "bootstrap";

  ...略
-
-   img {
-       display: none;
-   }

  ...略

スクリーンショット 2019-10-16 7.44.30.png

今度こそプロフィール画像が表示されるようになりました。

実際にGravatarに登録されている情報を使ってみる

example@railstutorial.orgというメールアドレスに対しては、実際にGravatarにプロフィール画像が登録されています。当該メールアドレスを使って、実際にGravatarに登録されている情報を参照してみましょう。

現時点でユーザーの登録情報を変更するフォームは実装していないので、ユーザーの登録情報の変更はrails consoleから行っていきます。

# rails console

>> user = User.first
...略
>> user.update_attributes(name: "Example User",
?> email: "example@railstutorial.org",
?> password: "foobar",
?> password_confirmation: "foobar")
...略
=> true

>> exit

スクリーンショット 2019-10-16 7.54.08.png

Gravatarに登録されているプロフィール画像が表示されています。

サイドバーの最初のバージョン

ユーザーのshowビューにサイドバーを追加する

ユーザーのshowビューにサイドバーを追加していきましょう。まずは以下のように、app/views/users/show.html.erbを全面的に書き換えていきます。

app/views/users/show.html.erb
<% provide(:title, @user.name) %>
<div class="row">
  <aside class="col-md-4">
    <section class="user_info">
      <h1>
        <%= gravatar_for @user %>
        <%= @user.name %>
      </h1>
    </section>
  </aside>
</div>

ポイントは以下です。

  • サイドバーは、HTML5のaside要素を使って実装している
  • HTML全体として、以下のクラスを使っている
    • row
    • col-md-4

rowクラスとcol-md-4クラスは、いずれもBootstrapフレームワークで使われているクラスの名前です。

SCSSを使ってサイドバーなどのユーザー表示ページにスタイルを与える

サイドバーの構成・クラス名が決まると、SCSSでスタイルを与えることができるようになります。今回は、以下のようなスタイルを与えていきます。

app/assets/stylesheets/custom.scss
    ...略
+
+ /* sidebar */
+
+ aside {
+     section.user_info {
+         margin-top: 20px;
+     }
+     section {
+         padding: 10px 0;
+         margin-top: 20px;
+         &:first-child {
+             border: 0;
+             padding-top: 0;
+         }
+         span {
+             display: block;
+             margin-bottom: 3px;
+             line-height: 1;
+         }
+         h1 {
+             font-size: 1.4em;
+             text-align: left;
+             letter-spacing: -1px;
+             margin-bottom: 3px;
+             margin-top: 0px;
+         }
+     }
+ }
+
+ .gravatar {
+     float: left;
+     margin-right: 10px;
+ }
+
+ .gravatar_edit {
+     margin-top: 15px;
+ }
    ...略

ここまでコードを追加した時点において、/users/1をブラウザで表示した結果です。

スクリーンショット 2019-10-16 12.34.29.png

演習 - Gravater画像とサイドバー

1. (任意) Gravatar上にアカウントを作成し、あなたのメールアドレスと適当な画像を紐付けてみてください。メールアドレスをMD5ハッシュ化して、紐付けた画像がちゃんと表示されるかどうか試してみましょう。

メールアドレスをMD5ハッシュ化する手順は、Railsコンソールで試してみます。「文字列を引数として与えてMD5ハッシュを生成する」というメソッドは、RubyのDigest::MD5::hexdigestでしたね。

# rails console --sandbox

>> Digest::MD5::hexdigest([Qiitaの登録メールアドレス])
=> "0aad88c4503ba3e1308c13025b89d4e5"

Qiitaの登録メールアドレスのMD5ハッシュが得られました。というわけで、Webブラウザで https://secure.gravatar.com/avatar/0aad88c4503ba3e1308c13025b89d4e5 にアクセスしてみます。きちんとQiitaのプロフィール画像が表示されています。

2. 7.1.4で定義したgravatar_forヘルパーをリスト 7.12のように変更して、sizeをオプション引数として受け取れるようにしてみましょう。

うまく変更できると、gravatar_for user, size: 50といった呼び出し方ができるようになります。

app/helpers/users_helper.rb
  module UsersHelper
-   def gravatar_for(user)
+   def gravatar_for(user, options = { size:80 })
      gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
+     size = options[:size]
-     gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
+     gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
      image_tag(gravatar_url, alt: user.name, class: "gravatar")
    end
  end

app/views/users/show.html.erbにおいて、gravatar_forメソッドにsize属性を与えず、メールアドレスがexample@railstutorial.orgである場合、Gravatarのプロフィール画像のURLがhttps://secure.gravatar.com/avatar/bebfcf57d6d8277d806a9ef3385c078d?s=80となります。

app/views/users/show.html.erbの内容に以下の変更を加えたらどうなるでしょう。gravatar_forメソッドのsize属性に50という値を与えたものです。

app/views/users/show.html.erb
  <% provide(:title, @user.name) %>
  <div class="row">
    <aside class="col-md-4">
      <section class="user_info">
        <h1>
-         <%= gravatar_for @user %>
+         <%= gravatar_for @user, size: 50 %>
          <%= @user.name %>
        </h1>
      </section>
    </aside>
  </div>

スクリーンショットは以下のようになりました。Gravatarのプロフィール画像のURLはhttps://secure.gravatar.com/avatar/bebfcf57d6d8277d806a9ef3385c078d?s=50となっています。

スクリーンショット 2019-10-16 18.26.18.png

3. 先ほど変更したリスト 7.12を、リスト 7.13のように置き換えてもうまく動くことを確認してみましょう。この2つの実装方法はどういった違いがあるのでしょうか? 考えてみてください。

以下はオプションハッシュを使ったコードに対するキーワード引数を使ったコードの差分です。

app/helpers/users_helper.rb
  module UsersHelper
-   def gravatar_for(user, options = { size:80 })
+   def gravatar_for(user, size: 80)
      gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
-     size = options[:size]
      gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
      image_tag(gravatar_url, alt: user.name, class: "gravatar")
    end
  end

app/views/users/show.html.erbにおいて、gravatar_forメソッドにsize属性を与えず、メールアドレスがexample@railstutorial.orgである場合、Gravatarのプロフィール画像のURLがhttps://secure.gravatar.com/avatar/bebfcf57d6d8277d806a9ef3385c078d?s=80となります。

gravatar_forメソッドのsize属性に値50を与えた場合、Gravatarのプロフィール画像のURLはhttps://secure.gravatar.com/avatar/bebfcf57d6d8277d806a9ef3385c078d?s=50とります。

オプションハッシュとキーワード引数の違い

「オプションハッシュの場合、引数の組がハッシュとしてひとかたまりにされており、ハッシュそのものを別のメソッドに渡すこともできる。一方のキーワード引数は、引数そのものはひとまとまりのオブジェクトにされていない。」というのが大きな違いかと思います。「別メソッドにオプションハッシュそのものを渡すことにより、呼び出し側のメソッドの内部構造を知らなければならなくなる。これはメソッド同士の結合度が高くなってよろしくない」という問題は考えられます。


  1. テスト環境でデバッグ情報が表示されても、「ユーザーに見えてはならない情報が見えてしまう」等の問題に直接つながるわけではありません。しかしながら、「デバッグ情報が開発環境以外で表示されるのは望ましくない」というのもまた事実です。 

  2. データの作成・表示・更新・削除は、総称して「CRUD」と呼ばれます。「Create, Read, Update, Delete」の略です。 

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0