can などの CanCanCan のメソッドにアクセスするより良い方法はありますか?モデルで?
概要
CanCanCan のメソッドはコントローラーまたはビューでのみ使用できますが、モデル内、具体的にはモデルの save メソッド内でアクセスしたいと考えています。この問題に対して私が使用する回避策は次のとおりです。save を呼び出す前に、モデル内に attr_accessor :ability を作成し、コントローラー内でそれに Abability オブジェクトを割り当てます。
class Example
include ActiveModel::Model
attr_accessor :ability
def save
if ability.can?(:create, SomeOtherModel)
...
end
end
end
class ExamplesController < ApplicationController
def create
@example = Example.new(params[:example])
@example.ability = Ability.new(current_admin_user) #note: current_admin_user can be several separate models such as Admin, Support
if @example.save
...
end
end
end
can を呼び出すより良い方法はありますか?モデル内から?セキュリティの観点などから、このソリューションに問題はありますか?
解決策
モデルにアビリティ メソッドを追加して、can? を委任することもできます。方法:
# app/models/user.rb
class User
delegate :can?, :cannot?, to: :ability
def ability
@ability ||= Ability.new(self)
end
end
some_user.can? :update, @article
https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://github.com/CanCanCommunity/cancancan/blob/develop/docs/define_check_abilities.md
この解決策では、能力をチェックする必要があるすべてのモデルで能力メソッドを定義する必要があると思います。そのため、コードが重複する可能性があります。
セキュリティの観点からは、予期せぬ事態を招く可能性があります。コントローラーは、モデルの許可された属性のみを作成/更新する強力なパラメーターをすでにサポートしています。
たとえば、サポートが一部の属性のみを更新でき、管理者がすべての属性を更新できる場合、モデル内でそれをどのように制御しますか?
また、コントローラーで能力をチェックすると、ユーザーのアクションを防止し、サーバーへの不要なクエリを回避できます。
CanCan がコントローラーとビューで can メソッドが最適に機能することを推奨している理由は次のとおりだと思います。
https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://github.com/CanCanCommunity/cancancan/blob/develop/docs/controller_helpers.md