モデルを作る
生成
前準備
$rails g model User name:string email:string
これで必要なファイルが自動生成。
追記:
Rails3.2以降は属性の規定値がstringとなるため、省略可能となるようです。
$rails g model User name email
実際に作ってみる
user = User.new
user = User.new(name:"Sample", email:"example@test.com")
model生成直後はこんな感じで作れる。
でも実際は名前とか必須じゃないと困る。
ので、validation機構を追加。
Validation
class User < ActiveRecord::Base
validates :name, presence: true
validates :email, presence: true, uniqueness: {case_sensitive: false }
end
このvalidation機構を追加すると、Userを作るときに名前の正当性、emailの一意性(大文字小文字を区別しない)の検証が可能となる。
user = User.new()
user.valid?
=>false
user.save
=>false
User.Create()
=>false
どころでValidationって何がいいの?
=>ActiveRecord経由でDBに保存や変更をしようとした時、vlaidationに失敗すると変更をキャンセルするようになっている。
いろんなvalidation
他にも存在性だけでなく、正規表現を使ったemailの正しい書式や、文字数のvalidationとかも行える。
validates :email, presence: true, length: { maximum: 250 }, format: { with: /<regular expression>/ }
モデルのマイグレーション
$rails g migration add_index_to_users_email
インデックスを追加してみる。
class AddIndexToUsersEmail < ActiveRecord::Migration
def change
add_index :users, :email, unique: true
end
end
changeメソッドの中に何をするか書けば良い。
add_indexはインデックスを追加するメソッド。
$bundle exec rake db:migrate
マイグレーションを実行。
※マイグレーション:DBに保存されているデータを保持したまま、テーブルの作成やカラムの変更を行うこと。
テストあれこれ
普通のテスト
RailsのテストフレームワークはRSpecとかいろいろあるけど、とりあえず一番シンプルなやつを。
test "should be valid" do
@user = User.new(name:"Example User", email:"example@test.com")
assert @user.valid?
end
ちなみにコントローラやモデルのテストは自動生成されている。
インテグレーションテストを作る場合には、railsコマンドを使用する。
$rails g integration_test <テスト名>
実行
$bundle exec rake test
コールバック
例えば、emailは保存前に小文字に変換しておきたいとする。
before_save: { self.email = email.downcase }
と書くことで、user.saveをする前にemailを小文字に変換することができる。
この機構はコールバックを使っていて、無名関数を直書きししてもいいし、別のメソッドを割り当てても構わない。
before_save :downcase_email
def downcase_email
self.email = email.downcase
end
パスワード
下準備
bcryptのgemを追加。
gem 'bcrypt', '~>3.1.7'
$bundle install
あとは、modelにpassword_digest:string
という属性を追加した後に、has_secure_password
というメソッドを追加するだけで良い。
まずはマイグレーション
$rails g migration add_password_digest_to_users password_digest:string
$bundle exec rake db:migrate
パスワードの実装
class User < ActiveRecord::Base
...
has_secure_password
end
こうすると、ハッシュ化されたパスワードをDB内のpassword_digest
という属性に保存できるようになる。
さらに、Userモデルに対してpassword
とpassword_confirmation
が使えるようになる。
パスワードのテストとvalidation
このpassword
とpassword_confirmation
属性は強制的にvalidation機構が追加されているので、
初めて追加した時はテストには軒並み失敗するようになっている。
ので、テストのデータにはちゃんとpassword/confirmationを追加する。
def setup
@user = User.new(name:"example user",email:"example@test.com",
password:"foobar",password_confirmation:"foobar")
end
さらにpasswordにはバリデーションも簡単に追加できる。
validates :password, presence: true, length: { minimum: 6 }