前提
書籍アプリみたいなのを前提に書いています
railsの更新系
createメソッド
値の設定、DBへの保存までを一気に行うメソッド
irb(main):014:0> Book.create(
irb(main):015:1* name: "キングダム",
irb(main):016:1* published_on: Time.parse("20201024").ago(2.months),
irb(main):017:1* price: 498,
irb(main):018:1* publisher: Publisher.find(1),
irb(main):019:1* )
上記を分解して記述する方法
newメソッド
モデルオブジェクトの作成
createメソッドとは違い、保存はされていない
saveメソッドを使い保存を行う
irb(main):001:0> book = Book.new
=> #<Book id: nil, name: nil, published_on: nil, price: nil, created_at: nil, updated_at: nil, publisher_id: nil>
irb(main):002:0> book.name = "キングダム"
=> "キングダム"
irb(main):003:0> book.published_on = Time.parse("20201024").ago(2.months)
=> 2020-08-24 00:00:00 +0900
irb(main):004:0> book.price = 498
=> 498
irb(main):005:0> book.publisher = Publisher.find(1)
=> "飛信隊"
irb(main):006:0> book.save
=> true
既存のデータを更新する際は
findメソッドなどでレコードを取得
→更新して再度saveメソッドを呼び出す
既存のデータを削除する際は
レコードを取得
→destroyメソッドを呼び出す
saveメソッドは不要
バリデーション
アプリケーションの要件時に、一定のルールでデータのチェックを行いたい場面が必ずある
- 本の名前は必ず入れたい
- 本の名前は20文字までに
- 価格は0円以上で
上記の要件の時↓
class Book < ApplicationRecord
略
validates :name, presence: true
validates :namae, length: { maximum: 25 }
validates :price, numericality: { greater_than_or_equal_to: 0 }
end
実際に本の名前を30文字でデータを保存しようとする
irb(main):004:0> book = Book.new
=> #<Book id: nil, name: nil, published_on: nil, price: nil, created_at: nil, updated_at: nil, publisher_id: nil>
irb(main):005:0> book.name = "a" * 30
=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
irb(main):006:0> book.price = 1000
=> 1000
irb(main):007:0> book.publisher = Publisher.find(1)
=> "飛信隊"
rb(main):008:0> book.save
=> false
saveメソッドの戻り値がfalseになり、レコードの保存に失敗している
保存せずにバリデーションだけを行いたいとき
saveメソッドの代わりにvalid?メソッドを使用する
rb(main):008:0> book.save
↓
rb(main):008:0> book.valid?
保存しようとして失敗した際にどのようなエラーが起こったのか、どのフィールドで発生したのか
という情報はインスタンスに記録される
上記のインスタンスとは何?
インスタンスとは、クラスを元に作られた具体的な個別データのこと
ではクラスとは何?
クラスとは、個別のデータ(値)の生成するための設計図・仕様のこと。
その情報はerrorsメソッドで取得することができる。
今回の場合は、book.errorsとすることで取得可能
また、book.errors.full_messagesと記述することで、読みやすい形にしてくれる
バリデーションと「!」付きのメソッド
保存メソッド(save、create、update、、、)に!がついている時の違い
- 「!」を伴わないメソッドはバリデーション失敗時には例外を起こさない
- 「!」を伴うメソッドはバリデーション失敗時には例外(ActiveRecord::RecordInvalid)が起こる
独自のバリデーション作成
少し、複雑なバリデーションを行ったり、メッセージをカスタマイズしたい場合
validateブロックを利用する。
下記が例になります
本の名前に"test"という文字列が含まれていたらバリデーションに引っかかるようにしている
また、errorsに何かしらの値が入っていればバリデーション失敗であると判定されるので、
地震でバリデーションの設定をする際は、引っかかった場合にerrorsにエラーメッセージを付与する
class Book < ApplicationRecord
略
validates :price, numericality: { greater_than_or_equal_to: 0 }
validate do |book|
if book.name.include?("test")
book.errors[:name] << "使用できない文字が含まれています"
end
end
end
DBの中身を見てみるコマンド
rails db
出力結果をわかりやすくするためには
sqlite> .mode line
sqlite> select * from book_authors;
1|1|3|2022-07-28 05:50:05.854258|2022-07-28 05:50:05.854258
2|2|3|2022-07-28 05:50:15.770756|2022-07-28 05:50:15.770756
3|1|4|2022-07-28 05:50:53.570274|2022-07-28 05:50:53.570274
sqlite> select * from book_authors;
id = 1
book_id = 1
author_id = 3
created_at = 2022-07-28 05:50:05.854258
updated_at = 2022-07-28 05:50:05.854258