6

ユーザーの役割に応じて、ビューの一部を非表示にしようとしています。

それでは、管理者だけが製品を破棄できるようにしたいとしましょう。通常のユーザーがレコードを破棄するのを防ぐためのコントローラーのコードに加えて、ビューで次のことを行います。

<% if current_user.admin? %>
  <%= link_to 'Delete', product, method: :delete %>
<% end %>

前のコードは機能しますが、省略によるエラーが発生しやすく、実行を許可されていないアクションへのリンクが通常のユーザーに表示される可能性があります。

また、後で新しい役割 (「モデレーター」など) が製品を削除できると判断した場合、削除リンクを表示するビューを見つけて、モデレーターがそれを表示できるようにするロジックを追加する必要があります。

また、管理者ユーザー (プロモーション、ユーザーなど) のみが削除できるモデルが多数ある場合、すべての if を維持するのは非常に困難です。

それを行うより良い方法はありますか?たぶん、ヘルパーなどを使用していますか?私はおそらくこのようなものを探しています:

<%= destroy_link 'Delete', product %> # Only admins can see it
<%= edit_link 'Edit', promotion %> # Again, only admins see this link
<%= show_link 'Show', comment %> # Everyone sees this one

私に似た次の 2 つの質問を見つけましたが、いずれも私の質問に答えませんでした。

Rails でのユーザー ロールに基づく表示と非表示

Ruby on Rails (3) ビューの一部を非表示にする

4

4 に答える 4

8

専門家を強くお勧めします。

モデルごとに「ポリシー」を作成できます。Productモデルの場合、ProductPolicy次のような

class ProductPolicy < ApplicationPolicy
  def delete?
    user.admin?
  end
end

あなたの見解では、このようなことができます

<% if policy(@post).delete? %>
  <%= link_to 'Delete', product, method: :delete %>
<% end %>

後でmoderatorロールを追加する場合は、ポリシー メソッドを変更するだけです

class ProductPolicy < ApplicationPolicy
  def delete?
    user.admin? || user.moderator?
  end
end
于 2013-07-29T20:30:51.947 に答える
2

そこで、IF をビューの外に移動する方法を考え出しました。まず、application_helper.rb で link_to ヘルパーをオーバーライドします。

def link_to(text, path, options={})
  super(text, path, options) unless options[:admin] and !current_user.admin?
end

次に、私の見解では次のように使用します。

<%= link_to 'Edit Product', product, admin: true, ... %>

これにより、通常のユーザーは管理リンクを表示できなくなりますが、div、テーブルなど、内部にコンテンツを含む他の html タグの場合は、if が引き続き必要になります。

于 2013-07-31T15:04:06.170 に答える
1

CanCanは、ユーザーの役割ごとに「能力」を定義できるもう 1 つの gem です。ビューではif can? :delete, @post、ユーザーがその特定の投稿を削除できるかどうかを確認するようなものを使用できます。

于 2013-07-30T00:10:51.593 に答える