心はいつも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
いまだにユビキタスなSONYとクラウドに向かうApple

PS3のトルネが良さそう@ヤマダ電機。PS3本体とチューナーの2台になってスッキ …

no image
RubyとRailsのお作法

コーディングスタイルって結構気になります。 最初につとめた会社で、プログラミング …

BiglobeでWimax契約して怒った

久々にダメサービスに遭遇して怒ったので書きます。 BiglobeでWimax契約 …

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

3.1章は静的ページの追加。これをトップページとして後で色々追加していきます。 …

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

9.3.4パーシャルのリファクタリング、です。 テストパスしているのでリファクタ …

メタプログラミングRuby第1章

初めてのRuby2章と8章をやったところで、メタプログラミングRubyに進みます …

no image
Ruby on Railsのインストール

Rubyのアップデートが終わったので、いよいよRailsをインストールします。 …

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

5.2SassとAsset Pipeline、です。 ここは読み物系です。読んで …

no image
railsのエラーメッセージを日本語化

message:で渡すエラーメッセージや、その他いろんな箇所を日本語化します。 …

no image
RailsとRubyのインストール済みバージョン確認し、Rails3.2+Ruby1.9に戻してみる。

Rails3.2で作る必要があったので、Rails4はいったんおいといてRail …