0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ActiveModel::Errorsインスタンスから、エラー対象のモデルのインスタンスを取得する

Posted at

環境

rails: 6.0.3.6
ruby: 2.6.5

結論

errors.instance_values["base"]

を用いることで、対象のインスタンスを取得することができる。

背景

localeが使われていないプロダクトで、localeを少しづつ導入を進めていた。
localeが使われていないので、model内で、バリデーションメッセージを全て手入力で入れていた。

hoge.rb
validate: name, present: {message: 'hogeを入力してください'}

そのため、slimのrailsフォームのエラーメッセージを表示する共通テンプレートの中で、エラーメッセージを出力するロジックが以下のように書かれていた。

form_error.html.slim
- errors.messages.values.each |message| do
   p = message

直面したこと

一気にlocaleを反映させるのはビッグコミットになるため、一部機能から順に差し替えていった。

hoge.rb
validate: name, present: true

しかし、そうすると、

form_error.html.slim
- errors.messages.values.each |message| do
   p = message /'を入力してください'と出てしまう

そのため、「locale対応している場合はfull_messagesを、そうではない場合はmessages」を出すことで対応することに。
このファイルの中で、このモデルがlocal対応しているかどうかを判別して処理を分けようと試みたが、errorsから「どのモデルのエラーなのか」を取得する方法が出てこなかった。
(簡単に取れそうなのに、、!!)

試したこと

console上では

[1] pry(main)> hoge = Hoge.new
[2] pry(main)> hoge.save
[3] pry(main)> hoge.errors
=> #<ActiveModel::Errors:0x00007ff0e2a6cb30
 @base=
  #<Hoge:0x00007ff0eaaa6738
   id: nil,
   name: nil>,
 @details=
  {:name=>[{:error=>:blank}]}]},
 @messages={:name=>["を入力してください"]}>

と出ていたが、

hoge.errors.base
-> undefined method `base' for #<ActiveModel::Errors:0x00007ff0e2a6cb30>

あれ、取得できない。

こういう時はrailsに聞くのが一番。

hoge.errors.methods
->  :to_hash,
    :full_messages,
    :delete,
    :to_a,
    .
    .
    :instance_values,
    .
    .

それっぽいの見つけた!

hoge.errors.instance_values
-> {"base"=>
  #<Hoge:0x00007ff0eaaa6738
   id: nil,
   name: nil>,
 "messages"=>{:name=>["を入力してください"]},
 "details"=>
  {:name=>[{:error=>:blank}]}

hashで中身を返してくれるらしい。

暫定コードとしてはこんなかんじ。

form_error.html.slim
ruby:
  error_messages = if I18n.exists?("activerecord.attributes.#{errors.instance_values["base"].class.name.underscore}")
                     errors.full_messages
                   else
                     errors.messages.values
                   end
- error_messages.values.each |message| do
   p = message

早く全てlocale移管したい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?