データベースに記述する
そもそもRails側でやらなくても、データベースにデフォルト値をセットする機能が備わっているのでそっちを使う。
マイグレーションで書くとこんな感じ
create_table :posts do |t| t.string :name, default: "nanashi" t.timestamps end
試してみる。しっかりとデフォルト値が設定されているのがわかる。
Post.new.name => "nanashi"
DBに書くのでRailsに依存しないメリットがありつつ、既存のデータベースについてはマイグレーションしなきゃいけないし、仕様変更のためにスキーマを変えなきゃいけないのはちょっと面倒かも。。
attributeを使う
Rails5からActiveRecordにattributes APIというのが追加された。
これを使うとモデル内にデフォルト値をセットできる。
class Post < ApplicationRecord attribute :name, :string, default: 'nanashi' end
試してみる
Post.new.name => "nanashi"
詳しいドキュメントは以下
一番シンプルでかつモデル内に記述できるので相当強い方法だが、Rails5以上でないと使えないぐらいしかデメリットが出てこない。。。。使おうな
after_initializeを使う
結論から言うと、この方法は副作用が大きいので推奨されてない しかし実装が簡単なのと、とっつきやすい点から結構使われてしまっている方法
RailsのActiveRecordにはいくつもコールバックが用意されていて、after_initialize()でデフォルト値を入れてしまおうというやり方である。
class Post < ApplicationRecord after_initialize :set_default, if: :new_record? private def set_default self.name ||= "nanashi" end end
なぜ new_record?
が必要かというと、なにもafter_initializeが走るのはモデルで新しいレコードのインスタンスを生成したときだけではなく、Post.all
とかで既存のDBから取得したときも当然インスタンスがレコード分だけ生成されるのでafter_initalizeは走ってしまうからである。
ただ、副作用があるといったのはafter_initializeが思わぬときに実行されるケースがあるからで、Railsのバージョンが古いとかそういう話以外では使わないほうが良さそう。。。
ちなみに他の before_validation
とか before_save
のコールバックでデフォルト値をいれようとするのは禁じ手である
他
あともう一つぐらいバッドノウハウなやり方があった気がするんだけど()、わすれた。。