今まで機械的にモデル作成をしてきたので、ここらで整理
モデルとは
Railsでは、データモデルで使用するデフォルトのデータ構造のことをモデルと呼びます。
また、データベースとやりとりするデフォルトのRailsライブラリはActive Recordと呼ばれ、そのActive Recordは、データオブジェクトの作成/保存/検索のためのメソッドを持っている。
モデルの作成
$ rails generate model User name:string email:string
このコマンドの実行により、マイグレーションファイルとmodel用のrbファイル(ここでは、user.rb)が作成されるが、この段階ではデータベースは作成されていない。データベースに反映する情報が作成されたに過ぎない
$ rails db:migrate
このコマンド入力により、db/development.sqlite3
という名前のファイルが生成されます。(これがSQLiteデータベースです。)
DB Browser for SQLiteというツールを使うと、データベースの構造を見ることができます (Cloud IDEを使っている場合は、ファイルをダウンロードする。
マイグレーションファイル
マイグレーション自体は、データベースに与える変更を定義したchange
メソッドの集まりです。
model用のrbファイル
class User < ActiveRecord::Base
という構文で、User
クラスはActiveRecord::Base
を継承するので、Userモデルは自動的にActiveRecord::Base
クラスのすべての機能を持ちます。
モデルに対して制限をかける場合はこのファイルに記載していく(validation)
一意性のあるデータ(被っちゃダメという制限)
問題点①:データ量が多くなると、検索時間がかかるため、新規ユーザーが2重クリックした際に、2重登録される場合がある。→インデックスをつけて対応
問題点②:デフォルトでは、大文字と小文字は区別されない。
→ before_save メゾットを使う。
インデックスをつける(問題点①への対応)
インデックス(索引)をつけることにより、検索の時間を短縮するイメージ
$ rails generate migration add_index_to_users_email
※メールアドレスを一意性にする場合
このコマンドにより新しいマイグレーションが作成されるが、何も定義されていない
なので、以下を追記
class AddIndexToUsersEmail < ActiveRecord::Migration[5.1]
def change
add_index :users, :email, unique: true ←これを追記
end
end
そして
$ rails db:migrate
デーダーベースに保存する前に全て小文字に置き換えてしまう。(問題点②への対応)
確認用パスワードの設定 (gem bcrypt)
gem をインストール (gemfileに追加)
source 'https://rubygems.org'
gem 'rails', '~> 5.1.6'
gem 'bcrypt' これを追加
gem 'bootstrap-sass', '3.3.7'
gem 'puma', '~> 3.7'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'jquery-rails'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
group :development, :test do
gem 'sqlite3'
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
group :development do
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2' gem 'spring' gem 'spring-watcher-listen', '~> 2.0.0'
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
model に 「password_digest」カラムを追加しなければならない
$ rails g migration add_password_digest_to_users password_digest:string
$ rails db:migrate
model用のrbファイルに追加
class User < ApplicationRecord
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maxinum: 50 }
VALID_EMAIL_REGEX = /\A[\w+-.]+@[a-z\d-.]+.[a-z]+\z/i
validates :mail, presence: true, length: { maxinum: 100 },
format: { with: VALID_EMAIL_REGEX },
uniquness: true
has_secure_password ←これを追加
end
passwordに存在性のバリデーションをかける
validates :password, presence: true
となるが、情報更新の時にまたパスワードを打ちたくないという時は、
validates :password, presence: true, allow_nil: true
にすれば良い。このように設定しても、登録の際は、has_secure_passwordが働くので、パスワードの認証は必要になる。
独自のバリデーションを作成する
今回は、退勤情報の入力は、出勤情報が存在するときだけとするような制限を作成
validate :finished_at_is_invalid_without_a_started_at
これを定義する
def finished_at_is_invalid_without_a_started_at
errors.add(:started_at, "が必要です") if started_at.blank? && finished_at.present?
end
コメント