Ruby
Rails

Railsのattributeはバリデーションではなくキャスト

どうも、ITのんびりです

モデルに書くattributeの意味がいまいち分かっていなかったので、調べてみました


使用例

attribute :id, :integer

こんな感じでパラメーター名と型を書きますよね

最近まで意味がよく分からず、「idのデータ型をintegerに限定しているのかなあ」と何となく思っていました


バリデーションではなくキャスト

attributeはバリデーションを設定しているのではなく、指定した型以外のデータが送られてきたら指定した型に変換(キャスト)します


attribute(name, cast_type = Type::Value.new, **options)

cast_typeで指定したtypeではない型のデータが飛んできたら指定したtypeにcastします

attribute :id, :integer

integerで指定して10.1がきたら10にcastします

attribute :flag, :bool

boolで指定して"false"という文字列が飛んできたらbooleanのfalseにcastします


バリデーションとの順番

attributeでキャストしてからvalidationが判定されるようです

attribute :id, :integer

validates :id, numericality: { only_integer: true }

idを整数にcastして、整数のバリデーションをかけるとします

idが10.1で送られてきたら、attributeで10にcastされます

idが10で整数なので、only_integer: trueのバリデーションは通ります

整数のバリデーションをかけているのに、10.1が送られてきてバリデーションが通るのはよくないですね(10にcastされているとはいえ)

バリデーションをかけるときは、castの影響を考えてするようにしましょう

参考記事

Rails5: ActiveRecord標準のattributes API(翻訳)