読者です 読者をやめる 読者になる 読者になる

ぞえの技術めも

Ruby on Rails勉強中

【127日目】【1日20分のRailsチュートリアル】【第10章】アカウント有効化向けにauthenticated?メソッドを変更する

Ruby on Railsチュートリアル(第3版)

今日は「10.1.3 アカウントを有効化する」から。

10.1.3 アカウントを有効化する

リスト10.23のとおりにメールが生成できたら、今度はAccountActivationsコントローラのeditアクションを書いて、実際にユーザーを有効化できるようにする必要があります。

editアクションが必要なのか。

メタプログラミングRubyが有するきわめて強力な機能であり、Railsの一見魔法のような機能 (訳注: 「黒魔術」と呼ばれることもあります) の多くは、Rubyメタプログラミングによって実現されています。
ここで重要なのは、sendメソッドの強力きわまる機能です。

何を言っているのか分からないよぉ…。
例を見てもイマイチピンとこない。

「sendメソッドすごい!」って覚えておけばいいんだろうか。。。。

sendメソッドの動作原理がわかったので、それに基いてauthenticated?メソッドを書き換えます。

def authenticated?(attribute, token)
  digest = self.send("#{attribute}_digest")
  return false if digest.nil?
  BCrypt::Password.new(digest).is_password?(token)
end

トークンが何種類かあって、それぞれ認証が必要だけど処理は似てるから一般化するためにsendメソッド使う、ってことだろうか。。。
使わなくても書けるんだよね。似たようなメソッド増えるけど、てことかな。
確かにメソッドとかまとめられた方がいいもんね。うーん、不思議だな~

以上の説明を実際のUserモデルに適用してできた、一般化されたauthenticated?メソッドをリスト10.24に示します。

authenticated?メソッドを下記のように変更。

app/models/user.rb

class User < ActiveRecord::Base
  :
  # トークンがダイジェストと一致したらtrueを返す
  def authenticated?(attribute, token)
    digest = send("#{attribute}_digest")
    return false if digest.nil?
    BCrypt::Password.new(digest).is_password?(token)
  end
  :
end

リスト10.24のキャプションに示されているとおり、テストスイートはREDになります。

なりますね。エラー出てる。

$ bundle exec rake test
43 tests, 171 assertions, 0 failures, 3 errors, 0 skips

テストが失敗する理由は、current_userメソッド (リスト8.36) とnilダイジェストのテスト (リスト8.43) の両方で、authenticated?が古いままになっており、引数も2つではなくまだ1つのままです。

authenticated?メソッド使ってる箇所を修正。パスはテスト実行時のエラーに出力されてるのでそこ見れば分かる。

にしてもリファクタリングする度修正するのってちょっとめんどくさいけど…実際に作るときは始めから気をつければいいんだろうな。。。
そしてテストしっかり書く。だいじ。

app/helpers/sessions_helper.rb

  :
  # 現在ログイン中のユーザーを返す (いる場合)
  def current_user
      :
      if user && user.authenticated?(:remember, cookies[:remember_token])
      :

test/models/user_test.rb

  test "authenticated? should return false for a user with nil digest" do
    assert_not @user.authenticated?(:remember, '')
  end

エラー出なくなりました。

$ bundle exec rake test
43 tests, 175 assertions, 0 failures, 0 errors, 0 skips

今日の学習時間は【30分】

次は「10.1.3 アカウントを有効化する」のeditアクション書くところから。