大まかな流れの自己整理が目的のため、不足・誤り等あれば追記していきますのでご容赦頂けますと幸いです。
なお、筆者は書籍版+動画版で学んでいるため、本記事はチュートリアル「sample_app」寄りになります。
(講師:安川さんの「エラーは怖くない、エラーは味方!」のメッセージは個人的にかなり励みさせてもらってます😅)
環境
・ AWS
・ Ruby 2.6.3p62
・ Rails 5.1.6
6.0 入る前に
Active Record
『Ruby⇆SQLの翻訳機』とされる。
Ruby → 変数に一時的な保存はできるが、ユーザ情報など永続的な保存できない
SQL → DBに永続的に保存できるが、CRUD処理などで別言語として習得が必要
RailsのActive Record(AR)を適用すると、DB関連をRubyのように書ける!
ex.「DBからemailのデータを探したい」
>> user = User.find_by(email: "mhartl@example.com")
今後お世話になるのでメモしておきました。
< 参考 >
【初心者向け】RailsのActive Recordの解説&メソッドまとめ
gitのブランチを分ける
何か不具合が起こったら、ブランチごと消せばok!
$ git checkout -b 'modeling-users'
6.1 Userモデル
Userモデル
カラム | 型 |
---|---|
id | integer |
name | string |
string | |
created_at | datetime |
updated_at | datetime |
※ タイムスタンプ等はマジックカラム(Magic Column)と呼ばれ、デフォルトで設定のためモデル生成時は定義しない。
Userモデルを生成する。
マイグレーションファイルが生成される(マイグレーションの自体は、データベースに与える変更を定義したchangeメソッドの集まり)。
$ rails generate model User name:string email:string
db/development.sqlite3
という名前のバイナリファイルが生成される。(これがSQLiteデータベースの実体)。
バイナリファイルの確認
db/development.sqlite3
はバイナリファイル(binary file)と呼ばれコンピュータ用(ex.^@^@^@...)だが、これをダウンロードしてDB Browser for SQLiteというアプリで中身の確認ができる。
生成されたマイグレーションファイルに対し、マイグレーションを実行(適用)
$ rails db:migrate
サンドボックスモードでのconsoleの起動
コンソールを使いたいがDB反映させたくないなど試験的に動かしたい場合、
サンドボックスモードで起動するとコンソールの動きが1つのトランザクション(「ここからここまでワンセット」な処理単位)となり、行った変更はロールバック(DBのトランザクション処理において、変更等を取り消してモード開始前のものに戻すこと)ができる。
< 参考 >
rails console まとめ - kzy52's blog
「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
$ rails console --sandbox
Running via Spring preloader in process 5446
Loading development environment in sandbox (Rails 5.1.6)
Any modifications you make will be rolled back on exit
ユーザオブジェクトの新規作成、確認、変更、保存、生成+保存(同時)、削除は下記
普段、変数は保存されないが、メソッド使用っぽく代入ができる。
※ .destroy
で削除されたオブジェクトはメモリ上にはまだ残っている
>> testuser = User.new(name: "Michael Hartl", email: "mhartl@example.com")
>> testuser.name
>> testuser.name = "railstest"
>> testuser.save
>> testuser.destroy
6.2 ユーザーを検証する
名前が存在するか?フォーマットは正しいか?
名前やメールアドレスを検証(validation)する。
nameは空でないか?(存在性)
emailは重複していないか?(一意性)
検証項目例:存在性、一意性、フォーマット、文字数長さ
モデル(test/models/user_test.rb)に関してのみテストするコマンド
$ rails test:models
setup メソッド
有効なUserオブジェクト (@user) を作成する特殊なメソッド。メソッド内に書かれた処理は、各テストが走る直前に実行される。
(test/models/user_test.rb)
def setup
@user = User.new(
name: "Example User",
email: "user@example.com")
end
正規表現(メールの正規表現分解の一例)
正規表現 | 意味 |
---|---|
/\A[\w+-.]+@[a-z\d-.]+.[a-z]+\z/i | (完全な正規表現) |
/ | 正規表現の開始を示す |
\A | 文字列の先頭 |
[\w+-.]+ | 英数字、アンダースコア (_)、プラス (+)、ハイフン (-)、ドット (.) のいずれかを少なくとも1文字以上繰り返す |
@ | アットマーク |
[a-z\d-.]+ | 英小文字、数字、ハイフン、ドットのいずれかを少なくとも1文字以上繰り返す |
. | ドット |
[a-z]+ | 英小文字を少なくとも1文字以上繰り返す |
\z | 文字列の末尾 |
/ | 正規表現の終わりを示す |
i | 大文字小文字を無視するオプション |
Rubular
Rubyでの正規表現についてはRubularで試しながら学ぶことができる。
補足
Macでのバックスラッシュ ( \ ) の入力方法
「 option 」 + 「 ¥ 」
マイグレーションにお願いする
$ rails generate migration add_index_to_users_email
6.3 セキュアなパスワードを追加する
大まかな前提として、パスワードはそのまま保存せずにいったん不可逆な変換をかけてから保存する
1.Railsが用意したレールhas_secure_passoword
を使用
これが追加されると、
password
password_confirmationが一致してるかも検証される。
2. 保存場所であるpassword_digestを用意する
3. ハッシュ関数(ex. BCrypt)を1個選ぶ
〜以下、主要部(個人的)のみ抽出〜
app/models/user.rb
完成型
( has_secure_passoword の追加 )
class User < ApplicationRecord
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
end
password_digestカラム用のマイグレーションを生成
$ rails generate migration add_password_digest_to_users password_digest:string
add_columnメソッドを使って生成したusersテーブルpassword_digestカラムを適用させる
$ rails db:migrate
bcryptを使うため、bcrypt gemをGemfileに追加する
gem 'bcrypt', '3.1.12'
$ bundle install
app/models/user.rb にhas_secure_password等を追加する
class User < ApplicationRecord
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
end
test/models/user_test.rbのsetupメソッドにパスワード追加、テストに文字数を指定する
require 'test_helper'
class UserTest < ActiveSupport::TestCase
def setup
@user = User.new(name: "Example User", email: "user@example.com",
password: "foobar", password_confirmation: "foobar")
end
省略
test "password should be present (nonblank)" do
@user.password = @user.password_confirmation = " " * 6
assert_not @user.valid?
end
test "password should have a minimum length" do
@user.password = @user.password_confirmation = "a" * 5
assert_not @user.valid?
end
end
テストして終了
$ rails t