心はいつもAirPucci (空元気でもいいから)

毎日がPucciを着ているような気分

RailsTutorial4.0を高速で復習する。6.2.5章。

      2014/01/26


6.2.5一意性を検証する、です。メールアドレスをIDとして使うため(でなくとも)重複登録を防ぎます。
説明が長いのですが、ここで一つ要求事項が増えているので、確認します。

メールアドレスの要求事項

同じアドレスの重複登録はできない
メールアドレスは大文字、小文字を区別しない(大文字は小文字に変換する)

以上が追加になっています。

メールアドレスの一意性を保証するためには、もう1つやらなければならないことがあります。それは、メールアドレスをデータベースに保存する前にすべての文字を小文字に変換することです。その理由は、データベースのアダプタが常に大文字小文字を区別するインデックスを使っているとは限らないからです

先のテストではメールアドレスに大文字小文字混在を許可したテストを書いていたのですが、ここで矛盾します。ま、いいでしょう。

テストを書く

リスト6.17 大文字小文字を区別しない、重複するメールアドレスの拒否のテスト。
spec/models/user_spec.rb

require 'spec_helper'
略
  describe "email addressが登録済の場合" do
    before do
      user_with_same_email = @user.dup
      user_with_same_email.email = @user.email.upcase
      user_with_same_email.save
    end
    #validではないと検証する
    it { should_not be_valid }
  end
end

@user.dupで@userと同じユーザーを作り、その値をupcaseで大文字に統一して保存しています。
テストは失敗します。大文字と小文字の違いだけなのに、別のemailアドレスとして認識し登録できてしまうっぽい。

同じメールアドレスは登録できないようにする

リスト6.18 メールアドレスの大文字小文字を無視した一意性の検証
リスト6.20 email属性を小文字に変換してメールアドレスの一意性を保証する。
app/models/user.rb

class User < ActiveRecord::Base
 before_save { self.email = email.downcase }
略
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
end

RailsTutorialのuniqueness: { case_sensitive: false }の説明が意味不明。ようは、case_sensitive:falseオプションで大文字小文字を無視するそうです。なので、大文字でも小文字でも同じ物扱いになりました。

before_save { self.email = email.downcase }で、DB保存直前にemailを小文字変換してから保存しています。before_saveはRailsのCallback関数ですね。ActiveModel::Callbacks を見ると沢山掲載されています。

テストは成功します。

DB側でも一意性を確保する??

んが、ここで。重複の排除ならDBの機能使えばいいじゃないってことと、
連続クリック等があった場合によっては、 uniqueness: 指定があっても登録ができてしまうこともあるとかで、

やっぱりDB側のインデックス使って一意性の確保をします。rails g modelの時に指定できそうですが、後からmigrationファイルに書く必要があるとのこと。あくまでもSQL発行してDB操作するのは、rakeで実行されるmigrationファイルのようで、マイグレーション作成します。

rails g migration add_index_to_users_email

def change
endと、中身が空のmigration fileができます。

リスト6.19 メールアドレスの一意性を強制するためのマイグレーション。
db/migrate/[timestamp]_add_index_to_users_email.rb

class AddIndexToUsersEmail < ActiveRecord::Migration
  def change
    add_index :users, :email, unique: true
  end
end

usersテーブルのemailカラムにインデックスを追加し、オプションでunique: trueを指定して一意性を確保します。add_indexはRailsのメソッドですね。

このmigrationをDBに反映させると、

usersテーブルのemailに全然ユニークキーが作成されません。
どうしたものか。

Railsでは
schema.rbに
add_index “users”, [“email”], name: “index_users_on_email”, unique: true
と書く事で、DBの一意性を確保するのだそうです。あくまでもラッパーってことか。

だったらDBはSQLである必要はますますなくって、NoSQLがいいなと思う今日このごろ。

いったんコミットしたら、次は
6.3セキュアなパスワードを追加する
です。

 - テクニカル ,

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事

パーフェクトRuby 2章Rubyの基礎 2-5-5 クラスメソッド

p54 2-5-5 クラスメソッド インスタンスメソッドに対して、クラスに対して …

詳解 Objective-C 2.0 第3版

Rubyの言語仕様を勉強する傍ら、Objective-Cも言語仕様ベースで勉強し …

Eclipse CDTインストールでCould not find

さいたまスーパーアリーナで全スサノオ使い果たし力尽きてはや1ヶ月と1週間。世の中 …

MicrosoftのFutureVision 2019 vs 2011 vs 2010

Wiredで取り上げられたので、今日はMSのFutureVisionが話題でした …

no image
RailsTutorial4.0を高速で復習する。4.1章の途中から。

さて、4.1章の途中にある、変だなと思っている箇所、 リスト4.4 Homeペー …

no image
RailsTutorial4.0を高速で復習する。5.6章。演習1問目。

5.6演習です。 一問目。 リスト5.28の静的ページのテストコードは簡潔ですが …

no image
RailsTutorial4.0を高速で復習する。7.3章。

7.3ユーザー登録失敗、です。 ここでは、エラーメッセージの表示を実装します。 …

つながらないWimaxの電波倍返し

googleが見つかりませんと言われると、対外電波切れ。 本日は多発しています。 …

RailsTutorial4.0を高速で復習する。11.3章。

11.3ステータスフィード、です。 11.3.1動機と計画、です。 仕様 mic …

コンビニで切れないiPhone充電ケーブル買った

iPhone充電に使うライトニングケーブルって高いのに切れ易く涙目。 こんな感じ …