Gravatar画像とサイドバー
前節で基本的なユーザーページの定義は終わりましたので、今度は各ユーザーのプロフィール写真のあたりをもう少し肉付けし、サイドバーも作り始めましょう。
ここではGravatar(Globally Recognized AVATAR)
をプロフィールに導入してみましょう。
Gravatarは無料のサービスで、プロフィール写真をアップロード
して、指定したメールアドレス
と関連付けることができます。
その結果、 Gravatarはプロフィール写真をアップロードするときの面倒な作業や写真が欠けるトラブル
、また、画像の置き場所
の悩みを解決します。
というのも、ユーザーのメールアドレスを組み込んだGravatar専用の画像パスを構成するだけで、対応するGravatarの画像が自動的に表示されるからです。
ユーザー表示ビューに名前とGravatarを表示する
app/views/users/show.html.erb
<% provide(:title, @user.name) %>
<h1>
<%= gravatar_for @user %>
<%= @user.name %>
</h1>/
デフォルトでは、ヘルパーファイルで定義されているメソッドは自動的にすべてのビューで利用
できます。
ここでは、利便性を考えてgravatar_for
をUsersコントローラに関連付けられているヘルパーファイルに置くことにしましょう。Gravatarのホームページにも書かれているように、GravatarのURLはユーザーのメールアドレスをMD5という仕組みでハッシュ化しています。
Rubyでは、Digestライブラリのhexdigest
メソッドを使うと、MD5のハッシュ化が実現できます。
>> email = "MHARTL@example.COM"
=> "MHARTL@example.COM"
>> Digest::MD5::hexdigest(email.downcase)
=> "1fda4469bcbec3badf5418269ffc5968"
メールアドレスは大文字と小文字を区別しません
が、MD5ハッシュでは大文字と小文字が区別される
ので、Rubyのdowncase
メソッドを使ってhexdigest
の引数を小文字に変換
しています。
(本チュートリアルでは、リスト 6.32のコールバック処理で小文字変換されたメールアドレスを利用しているため、ここで小文字変換を入れなくても結果は同じです。ただし、将来gravatar_forメソッドが別の場所から呼びだされる可能性
を考えると、ここで小文字変換を入れることには意義があります。)
gravatar_for
ヘルパーを組み込んだ結果をリスト 7.9に示しました。
module UsersHelper
# 引数で与えられたユーザーのGravatar画像を返す
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
コードは、Gravatarの画像タグにgravatarクラス
とユーザー名のaltテキスト
を追加したものを返します
(altテキストを追加しておくと、視覚障害のあるユーザーがスクリーンリーダーを使うときにも役に立ちます)。
アプリケーションでGravatarを利用できるようにするために、まずはupdate_attributes
を使ってデータベース上のユーザー情報(メールアドレス)を更新
してみます。
>> user = User.first
(1.5ms) SELECT sqlite_version(*)
User Load (0.8ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.com", created_at: "2021-09-23 05:29:52", updated_at: "2021-09-27 16:05:45", password_digest: [FILTERED]>
>> user.update(name: "Example User",
?> email: "example@railstutorial.org",
?> password: "foobar",
?> password_confirmation: "foobar")
(0.1ms) begin transaction
User Exists? (0.9ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? AND "users"."id" != ? LIMIT ? [["email", "example@railstutorial.org"], ["id", 1], ["LIMIT", 1]]
User Update (4.3ms) UPDATE "users" SET "name" = ?, "email" = ?, "updated_at" = ?, "password_digest" = ? WHERE "users"."id" = ? [["name", "Example User"], ["email", "example@railstutorial.org"], ["updated_at", "2021-09-29 15:34:10.061966"], ["password_digest", "$2a$12$W69Q5IOpb6fONAdqQZWGNOeWCvE/kjXiFMZ16HdSdWpMF1fjazJce"], ["id", 1]]
(9.0ms) commit transaction
=> true
ユーザーのメールアドレスにexample@railstutorial.orgを使いました。
Gravatar上でこのメールアドレスとRailsチュートリアルのロゴを既に紐付けてあるので、上のように更新すると次の図 7.9のようになります。
図 7.1のモックアップに近づけるために、ユーザーのサイドバー
の最初のバージョンを作りましょう。
ここではasideタグ
を使って実装します。
このタグはサイドバーなどの補完コンテンツの表示
に使われますが、単独で表示することもできます。
rowクラス
とcol-md-4クラス
も追加しておきます。
これらのクラスはBootstrap
の一部です。
ユーザー表示ページを変更した結果を示します。
<% 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>
HTML要素とCSSクラスを配置したことにより、プロフィールページ(とサイドバーとGravatar)
にSCSSでスタイルを与えることができるようになりました
(テーブルCSSのルールが入れ子になっていますが、これができるのはAsset PipelineでSassエンジンが使われている場合に限られます)。
ページの変更の結果を図 7.10に示します。
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;
}
演習
1.(任意)Gravatar上にアカウントを作成し、あなたのメールアドレスと適当な画像を紐付けてみてください。
メールアドレスをMD5ハッシュ化して、紐付けた画像がちゃんと表示されるかどうか試してみましょう。
2.7.1.4で定義したgravatar_forヘルパーをリスト 7.12のように変更して、sizeをオプション引数として受け取れるようにしてみましょう。うまく変更できると、gravatar_for user, size: 50といった呼び出し方ができるようになります。重要: この改善したヘルパーは10.3.1で実際に使います。忘れずに実装しておきましょう。
module UsersHelper
# 引数で与えられたユーザーのGravatar画像を返す
def gravatar_for(user, options = { size: 80})
# size:50で画像の大きさを指定
size = options[:size]
gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
image_tag(gravatar_url, alt: user.name, class: "gravatar")
end
end
3.オプション引数は今でもRubyコミュニティで一般的に使われていますが、Ruby 2.0から導入された新機能「キーワード引数(Keyword Arguments)」でも実現することができます。先ほど変更したリスト 7.12を、リスト 7.13のように置き換えてもうまく動くことを確認してみましょう。この2つの実装方法はどういった違いがあるのでしょうか? 考えてみてください。
module UsersHelper
# 引数で与えられたユーザーのGravatar画像を返す
def gravatar_for(user, size: 80)
gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
image_tag(gravatar_url, alt: user.name, class: "gravatar")
end
end
実装方法の違いは長いか短いかしかわからない。
短い方で済むならそれでいいと思った。
キーワード引数のほが便利らしい。
={}
可変長のハッシュを受け取る引数オプション的な挙動を実現できます。
この引数の名前はもちろんoptions以外でも何でも構いません。