心はいつも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

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

  関連記事

no image
Ruby 1.9系をインストールする

Rubyのバージョン管理ができるrbenvをインストールしたらいよいよRubyの …

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

3.6高度なセットアップ、です。 この節を飛ばしても次の章以降には何の影響もあり …

Ruby on Railsを4.1.0にバージョンアップする

真央ロス真央廃を超えた腐まお状態な1ヶ月1週間、まるで娘が嫁に行った父親のごとし …

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

5.1.2BootstrapとカスタムCSS、です。 今までdivについていたイ …

herokuのWe’re sorry, but something went wrong.に苦しんだ

Rails3.2環境に戻してアプリを作ろうとしています。 herokuにpush …

OpneSSL,Readline,Libyamlをインストールする

先ほどインストールしたHomebrewを使って、rbenvをインストールしたいと …

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

7.1.2ユーザーリソース、です。 /user/newを/signupで表示させ …

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

9.2.3フレンドリーフォワーディング、です。 ログオンしていないユーザーが編集 …

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

11.2フォローしているユーザー用のWebインターフェイス、です。 モデルができ …

Provisioning fileが作成できない!

iPhoneアプリを公開するために、itunes connectでProvisi …