心はいつも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
RailsTutorial4.0を高速で復習する。3.3章。

テストコードが長くなったからリファクタリングするかも、、といいながら、静的ページ …

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

5.3レイアウトのリンク、です。 AboutはRailsらしくない、とおっしゃっ …

もうあかん!Mac OSXのスクロールを逆にする

OSXのいつのバージョンからだっけ? スクロールの向きが突如逆になったんですよね …

GitにRailsプロジェクトをpushする

HomebrewerでGitをインストールし、Rails 3.2やRails4. …

パーフェクトRuby 2章Rubyの基礎 2-8 様々な代入式

p66 2-8-1 多重代入 まとめて代入する横着なやり方。 a,b = 1,2 …

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

静的ページにaboutというページを追加するのですが、rails gを先にするの …

no image
gamilアカウントが乗っ取られました

朝起きてすぐ行うメール確認。iphoneでgmail接続できないってエラーが出る …

rails gでのファイル名、クラス名、アクション名

rails gすると、コントローラーとアクションができますが、 その書き方とファ …

Google Webfont使ってみたよ

地元に戻ってきてまず思ったのは「観光サイトを立ち上げたい」ということ。いや、観光 …