Подтвердить что ты не робот

CanCan: ограничение возможности пользователя устанавливать определенные атрибуты модели на основе их роли

У меня есть модель Post с атрибутом :published (boolean) и Пользователь с атрибутом role (строка). Существует три роли: ROLES = %w[admin publisher author]

Я не хочу, чтобы пользователи, чья роль автор, могли устанавливать или редактировать поле :published в модели Post.

Я использую CanCan (и RailsAdmin gem), и мой упрощенный файл Ability.rb выглядит так:

class Ability
  include CanCan::Ability
  def initialize(user)
    user ||= User.new

    if user.role? :admin
      can :manage, :all
    elsif user.role? :publisher
      can :manage, Post
    elsif user.role? :author
      # I want to prevent these guys from setting the :published attribute
    end

  end
end

У кого-нибудь есть какие-то советы для такого рода вещей?

4b9b3361

Ответ 2

Отправлено: Как использовать CanCan с rails admin для проверки прав собственности

Показывает, как сделать поле невидимым на основе роли пользователя.

UPDATE Мне удалось установить параметры в rails admin с помощью этого кода:

config.model User do
  edit do
    configure :organization do
      visible do
        bindings[:view]._current_user.max_role_name != 'admin' ? false : true
      end
    end

    configure :organization_id, :hidden do
      visible do
        true if bindings[:view]._current_user.max_role_name != 'admin'
      end
      default_value do
        bindings[:view]._current_user.organization_id if bindings[:view]._current_user.max_role_name != 'admin'
      end
    end

    include_all_fields
  end
end

Эта конфигурация скроет поле организации, если зарегистрированный пользователь не является администратором. Затем он отобразит поле organization_id (установлено в type = 'hidden) и установит значение по умолчанию.

Надеюсь, это поможет кому-то.

Ответ 3

Пока CanCan 2.0 не появится, я решил это, создав подкласс модели с ограниченной доступностью, например:

class AuthorPost < Post
  attr_protected :published
end

И затем дайте авторам доступ к AuthorPosts: can :manage => AuthorPost

Затем в вашем контроллере вы можете установить нужный ресурс в файле before_filter:

before_filter :set_resource
...
  private
    def set_resource
      if current_user and current_user.author?
        @resource = AuthorPost
      else
        @resource = Post
      end
      params[:post] ||= params[:author_post]
    end

Последнее предостережение: вы не сможете использовать load_and_authorize_resource в этом контроллере. Вам нужно будет сделать это вручную, как описано здесь: https://github.com/ryanb/cancan/wiki/Controller-Authorization-Example

Вам нужно заменить Project на @resource.

Я нахожусь на заборе относительно того, является ли это более или менее эффективным, чем метод, описанный в railscast. В моих целях он оставил оригинальную модель полностью неповрежденной, поэтому мой другой код не был затронут - и просто позволил мне предоставить некоторым пользователям меньше редактируемых полей.

Ответ 4

Есть способ, я сделал что-то подобное в моем проекте. Но CanCan - это не совсем ответ. Что вам нужно сделать, так это сделать attr_accessible в динамике модели на основе роли пользователя, поэтому, если вы являетесь администратором, вам разрешено обновлять опубликованное поле. Если нет, то при задании поля новое значение просто не будет выполняться при сохранении модели.

Railscasts снова приходит на помощь: http://railscasts.com/episodes/237-dynamic-attr-accessible

После получения внутренней части реализованной функции вы можете сделать что-то в форме frontend, обернув поле публикации в представлении с проверкой ролей или чем-то, чтобы показать или скрыть поле на основе пользователя. Грубый пример моей реализации...

<% if current_user.roles.where(:name => ['Administrator','Editor']).present? %>
    <%= f.label :display_name %>
    <%= f.text_field :display_name %>
<% end %>