コントローラーか制約か--権限を強制する最良の方法?

user_id フィールドを持つ server モデルを追加するプラグインを持っています。server の所有者のみが POST(あるいは PUT かもしれません——このアクションはサーバー上の Discourse インスタンスをコマンドラインで再構築するものです)を実行できるようにしたいと考えています。どちらがベストプラクティスなのか確信が持てません。

config/routes.rb には以下のような記述があります:

post “/upgrade/:id” => “servers#queue_upgrade”, constraints: PfaffmanagerConstraint.new

pfaffmanager_constraint.rb 内の matches?path_parameters[:action] をチェックし、そこで権限を強制することをお勧めしますか、それとも servers_controller.rb で行うべきでしょうか?

また、実際にはこのルートを変更して namespace :user の下に移動すべきだと思っています。そのため、この問題を解決すれば、その過程でこの問題も解決されるかもしれません。しかし、このコードはほぼ機能しており、他の人にもこのコードを試してもらいたいと考えています。

Rails のルートは以下にあります:
https://github.com/pfaffman/discourse-pfaffmanager/blob/master/config/routes.rb#L12

また、私のコントローラーでは権限の強制を試みています:
https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/controllers/pfaffmanager/servers_controller.rb#L53-L70

しかし、異なるユーザーが post を実行した際に、仕様テストでは 200 が返ってきています:
https://github.com/pfaffman/discourse-pfaffmanager/blob/master/spec/requests/servers_controller_spec.rb#L149-L157

どうやら、Ember にも何らかの方法でこれに対応させる必要があるようです。

条件を確認するために、before_action にメソッドを渡すことはできませんか?

パーミッションはコントローラーか制約側で適用する必要があると思います。モデル側は、誰が呼び出しているのかを把握していないはずです。

この件についてご検討いただき、誠にありがとうございます。

ユーザーが特定のアクションを実行できるかを確認するガーディアンメソッドが必要だと思います。例えば、can_upgrade_server? などです。

また、それを実装すれば、条件を確認して例外を発生させる guardian.ensure_can_upgrade_server! メソッドを使用できます。これはまさにあなたが求めているものだと思います。

おお、ガーディアンの手法ですね!はい、確認します!ありがとうございます。

guardian を使用しているモデルは user モデル のみです。guardian に関連する処理の大部分はコントローラー側で行われているようです。

例えば、categories コントローラーは ensure_can_create_category を使用していますが、これはおそらく lib/guardian.rb で自動的に生成されているものだと考えられます。

しかし現時点では、正しくインスタンス化する方法がわからず困っているため、guardian は使用していません。私のコントローラーには以下のようなコードがあります:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/controllers/pfaffmanager/servers_controller.rb#L54-L75

また、これをテストする specs は以下の通りです:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/spec/requests/servers_controller_spec.rb#L154-L181