modelについて ruby on rails

今まで機械的にモデル作成をしてきたので、ここらで整理

モデルの作成

$ 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

デーダーベースに保存する前に全て小文字に置き換えてしまう。(問題点②への対応)

selfは、メソッドを呼び出している時点でのユーザーオブジェクトを指しています。

確認用パスワードの設定 (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

コメント

タイトルとURLをコピーしました