心はいつも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
恐ろしや、WordPressのDBパスワードは平文でおいてある

先ほどサーバーのDBをいじっていてですね、、久々だったのでDBパスワード忘れてし …

no image
Rubyの%を使う記法のうち、 %w

Rubyで%を使う記法は、たのるー(たのしいRuby)によると、以下の6通り % …

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

6.2.2プレゼンスを検証する、です。いよいよモデルにコードを書いていきます。 …

WordPress子テーマの作り方

デザイン変更したairpucci、TwentyTwelveというWordPres …

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

第11章ユーザーをフォローする、です。ようやく最終章。1週間でできるつもりが3週 …

no image
wordpressはじめます

ブログを立ち上げるのは久しぶりです。 以前から、ブログメディアをやりたいと思って …

no image
@で始まるのが インスタンス変数

@ で始まるのが インスタンス変数 大文字で始まるのが 定数 文法書のどこに書い …

no image
MacBookAirは壊れるの?

1ヶ月ぶりにWindows機を立ち上げています。HDDのカリカリ言う音が冷や汗も …

no image
retweetボタンを追加してみました

最近いろんなブログで見かけるretweetボタン。ブログのエントリーについている …

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

8.1.3サインインのフォーム、です。 ログイン画面を作る 入力フォームをfor …