掲題の件、
備忘として書きます。
環境
[DB]
postgresql
[rails]
6.1.3.2
[active_admin]
2.9.0
何にハマったか
active_storageを使ってmodelに
has_one_attached :image1
has_one_attached :image2
みたいな実装をしていた。
ところがふとした拍子に、きっかけは不明なものの、(Heriokuにデプロイしたあとくらいから出てコードを戻したりしても解決しなかった)
そのテーブルのnewのぺージにアクセスすると下記のエラーが表示された。
エラー内容が意味不明な上に出るようになったきっかけも不明だったため(元はnewで画像の登録も出来ていた)
非常に困惑したがどうにか無理やり解決したのでその方法。
Rendered vendor/bundle/ruby/2.7.0/gems/activeadmin-2.9.0/app/views/active_admin/resource/new.html.arb (Duration: 53.2ms | Allocations: 11450)
Completed 500 Internal Server Error in 139ms (ActiveRecord: 19.3ms | Allocations: 19748)
ActionView::Template::Error (undefined method `persisted?' for #<Genre::ActiveRecord_Relation:0x00007f16023dbef8>):
1: insert_tag renderer_for(:new)
結果
active_adminのソースを読みながらnewページにアクセスしたときに何が起こるのか読み砕いてデフォルトの挙動をオーバーライドしたことにより解決出来た。
そのサンプルがこちら
app/admin/user.rb みたいなテーブルだったとして
ActiveAdmin.register User do
controller do
def get_resource_ivar
return super if super.try(:persisted?)
id = permitted_params[:id]
resource = User
.with_attached_image1
.with_attached_image2
if id.present?
resource.find(id)
else
resource.new
end
end
end
end
こう書く。まずsuperのメソッドで persisted? が呼べるなら問題ない。スルーする。
次にどうやらnewやeditに行ったときにactive_storageのrelationが悪さをしているようなので、
リレーションを追加してやる。
このとき、editとnewではidがある無しの違いがあるのでそこも考慮しないとどっちかでコケる。
結果、こう書いて動くようになったが正解かどうかはわからない。
あともっと他にいい書き方がありそうな気もするがコーディング規約的な話になってくるのでそこはよしなにやってほしい。
この記事が誰かの助けになったら幸いだ。