ruby on rails - manage - CanCan: limita la capacidad de un usuario para establecer ciertos atributos de modelo en función de su función
roles rails (4)
Echa un vistazo a esta publicación: ¿Cómo uso CanCan con el administrador de Rails para verificar la propiedad?
Muestra cómo hacer que un campo no sea visible en función de la función de un usuario.
ACTUALIZACIÓN Pude establecer opciones en el administrador de rieles con este código:
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
Esta configuración ocultará el campo de organización si el usuario que inició sesión no es un administrador. A continuación, mostrará un campo de ID de organización (establecido en type = ''hidden'') y establecerá el valor predeterminado.
Espero que esto ayude a alguien.
Tengo un modelo de publicación con un atributo :published
( booleano ) y un modelo de usuario con un atributo de role
( cadena ). Hay tres roles: ROLES = %w[admin publisher author]
No quiero que los usuarios cuyo rol es autor sean capaces de configurar o editar el campo :published
en el modelo de publicación.
Estoy usando CanCan (y la gema RailsAdmin) y mi archivo Ability.rb simplificado se ve así:
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
¿Alguien tiene algún consejo para hacer este tipo de cosas?
Hasta ahora no es posible. Pero de acuerdo con esto: https://github.com/ryanb/cancan/issues/326 esta característica debería estar en Cancan 2.0.
Actualización: puede ver esto en la sucursal de CanCan 2.0 aquí: https://github.com/ryanb/cancan/tree/2.0 en la sección "Atributos de recursos"
Hasta que sale CanCan 2.0, resolví esto creando una subclase del modelo con accesibilidad restringida, algo como:
class AuthorPost < Post
attr_protected :published
end
Y luego dé a los autores acceso a AuthorPosts: can :manage => AuthorPost
Luego, en su controlador, puede configurar el recurso que desea en un 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
Una última advertencia: no podrá usar load_and_authorize_resource
en ese controlador. Tendrá que hacerlo manualmente, como se detalla aquí: https://github.com/ryanb/cancan/wiki/Controller-Authorization-Example
Tendrá que reemplazar el Project
con @resource
.
Estoy en la cerca de si esto es más o menos efectivo que el método descrito en el railscast. Para mis propósitos, dejó el modelo original totalmente intacto, por lo que mi otro código no se vio afectado, y me permitió dar a algunos usuarios menos campos editables.
Hay una manera, hice algo como esto en mi proyecto. Pero CanCan no es del todo la respuesta. Lo que debe hacer es hacer que attr_accessible en su modelo sea dinámico según la función del usuario, por lo que si es un administrador, entonces puede actualizar el campo publicado. Si no, entonces al darle un nuevo valor al campo simplemente no se tomará cuando el modelo se guarde.
Railscasts viene al rescate una vez más: http://railscasts.com/episodes/237-dynamic-attr-accessible
Luego de implementar la parte de fondo de eso, entonces puede hacer algo al respecto en el formulario de frontend envolviendo el campo de publicación en la Vista con una verificación de roles o algo para mostrar u ocultar el campo según el usuario. Buen ejemplo de mi implementación ...
<% if current_user.roles.where(:name => [''Administrator'',''Editor'']).present? %>
<%= f.label :display_name %>
<%= f.text_field :display_name %>
<% end %>