ぞえの技術めも

Ruby on Rails勉強中

【47日目】【1日20分のRailsチュートリアル】【第6章】データベースにメールアドレスの一意性を設定する

Ruby on Railsチュートリアル(第3版)

今日は「6.2.5 一意性を検証する」のデータベースにも一意性の設定するところから。

6.2.5 一意性を検証する

実は、この問題はデータベースレベルでも一意性を強制するだけで解決します。
具体的にはデータベース上のemailのカラムにインデックス (index)を追加し (コラム6.2)、そのインデックスが一意であるようにすれば解決します。

概念的には分かった。やり方はこれから。

Railsではマイグレーションでインデックスを追加するらしい。

$ rails generate migration add_index_to_users_email
      invoke  active_record
      create    db/migrate/20160929021046_add_index_to_users_email.rb

ユーザー用のマイグレーションと異なり、メールアドレスの一意性のマイグレーションは未定義になっています。

一意性に関するインデックスを追加するコードを追記。

db/migrate/[timestamp]_add_index_to_users_email.rb

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

最後にデータベースのマイグレード。

$ bundle exec rake db:migrate

この時点では、(テストDB用のサンプルデータが含まれている) fixtures内で一意性の制限が保たれていないため、テストは失敗します。

試しにテスト実行してみたけど成功した。
コマンド違うのかな…??

$ bundle exec rake test:models
16 tests, 35 assertions, 0 failures, 0 errors, 0 skips

また、このfixtureは第8章になるまで使わない予定なので、今のところはこれらのデータを削除しておき、ユーザー用のfixtureファイルを空にしておきましょう (リスト6.30)。

どう関係があるのかよく分からないけど削除した。
fixtureのサンプルデータが見れてないのかな。。。

test/fixtures/users.yml

# empty

「いくつかのデータベースのアダプタは大文字小文字を区別するインデックスを使っている」という問題への対処です。

まだ終わらない。一意性の検証って大変。

今回は「データベースに保存される直前にすべての文字列を小文字に変換する」という対策を採ります。

なるほどねぇ。

ユーザーモデルにデータベース保存前(before_save)にメールアドレスを小文字に変換するコードを追加。

app/models/user.rb

  before_save { self.email = email.downcase }

メールアドレスの小文字変換に対するテストは演習として残しておきます (6.5)。

テスト要らないの?と思ってたところでした。

ようやく「6.2.5 一意性を検証する」が終了。
今日の作業時間は【22分】

次は「6.3 セキュアなパスワードを追加する」から。