activeadminはとても便利ですね!
簡単に管理画面を作成できるだけでなく、ある程度のカスタマイズにも対応できます。
何をしたいか
Railsではmodelにto_param
というメソッドがあり、これを上書きすることでURLに含まれる:id
を他のカラムにすることができます。
例えば以下のようにすることで、/events/:id/
のidをnameカラムにすることできます。
class Events < ApplicationRecord
def to_param
name
end
end
to_paramの上書きはしばしばやると思うのですが、activeadminでの対応方法がネットで見つけづらかったので、記事にしようと思います。
何が起こるか
上記のようにto_paramを上書きした場合activeadminではどうなるのでしょうか?
activeadminは今のモデル構造を分析することで自動的に管理画面を作成できるようになっています。そのためto_param
もしっかり認識してくれます。
しかし、上書きした状態でactiveadminで詳細画面や編集画面を見ようとするとエラーしてしまいます。
これは、admin/events
に表示される「閲覧・編集・削除」などのリンクがto_paramによってadmin/events/:name/
となっているものの、内部のfind
やwhere
ではidで検索していることに起因しています。
解決法
ActiveAdmin.registerのファイルに少しオプションを書くだけで対応できます。
ActiveAdmin.register Event do
# ここから
controller do
def find_resource
scoped_collection.where(name: params[:id]).first!
end
end
# ここまで
end
読んでいるだけで理解できそうです。
通常where(id: params[:id])
となるところをwhere(name: params[:id])
にするだけです。
注意点
公式には以下のような文言で注意点が書かれています。
Note that if you use an authorization library like CanCan, you should be careful
to not write code like this, otherwise **your authorization rules won't be
applied**:
```ruby
ActiveAdmin.register Post do
controller do
def find_resource
Post.where(id: params[:id]).first!
end
end
end
これはつまり、モデル名ではなく、scoped_collection
を使わないとadminの権限管理が機能が効かないよ。ということですね。みなさんも注意してください!