2011-07-29 10 views
14

¿Hay alguna manera de declarar attr_accessible para múltiples roles sin una tonelada de duplicación?Rails - Cómo declarar attr_accessible para múltiples roles sin duplicación

Si tengo varios roles de usuario, y se permite a cada función para editar un subconjunto diferente de atributos, esto es lo que mi declaración attr_accessible parece:

attr_accessible :first_name, :last_name, :active, :as => :admin 
attr_accessible :first_name, :last_name, :as => :manager 
attr_accessible :first_name, :last_name, :as => :guest 

me gustaría ya sea

  • A) definen una matriz de atributos accesibles que se pueden compartir entre roles diferentes o
  • B) definen una matriz de roles que pueden acceder a los mismos atributos

¿Esto es posible?

+0

¿Qué marco de autorización está utilizando que le permite restringir attr_accessible en los roles? Eso no es Rails AFAIK estándar. – Confusion

+1

Oh, estoy usando Rails 3.1, por lo que podría ser una característica más nueva. El argumento: as aparece en el módulo MassAssignmentSecurity (https://github.com/rails/rails/blob/master/activemodel/lib/active_model/mass_assignment_security.rb) –

Respuesta

4

Todo el código Ruby es todavía sólo Ruby código ... y es por lo tanto infinitamente hackable. por ejemplo,

ROLES = [:admin, :manager, :support, :user, :guest] 
ACTIVE_ROLES = [:admin, :support] 
ROLES.each do |role| 
    fields = [:first_name, :last_name] 
    fields += [:active] if ACTIVE_ROLES.include?(role) 
    attr_accessible *fields, :as => role 
end 
+0

Para las aplicaciones de Rails 3, consulte la respuesta de @AdrianMacneil –

3

¿Usted intentó algo como:

COMMON_FIELDS = [:first_name, :last_name] 

attr_accessible COMMON_FIELDS | [:active, :as => :admin] 
attr_accessible COMMON_FIELDS | [:as => :manager] 
attr_accessible COMMON_FIELDS | [:as => :guest] 

Otra forma posible (no probado):

attr_accessible :first_name, :last_name 
ADMIN_ACCESSIBLE = [:active] 
MANAGER_ACCESSIBLE = [] 
GUEST_ACCESSIBLE = [] 

protected 

def mass_assignment_authorizer 
    if role == :all 
    self.class.protected_attributes 
    else 
    super + (eval("#{role}_accessible".upcase) || []) 
    end 
end 
+0

Tenga en cuenta que solo funciona con Ruby 1.9 - [: as =>: admin] causará un error de sintaxis – makaroni4

44

Acabo de pasar un largo tiempo tratando de encontrar la mejor manera de hacerlo. ¡Parecía extraño que la gente de los rieles esperara que duplicaras un montón de código!

Después de algo de investigación en torno a la fuente de los carriles, resulta que usted puede simplemente pasar una matriz para asignar atributos a múltiples roles a la vez (: por defecto es el papel de registro activa por defecto)

attr_accessible :name, :email, :as => [ :default, :admin ]  
attr_accessible :featured, :as => :admin 

Sin rubí desordenado arrays en tu modelo!

+2

Simplemente quiero decir que este es un código más bonito y legible que la respuesta aceptada. – theodorton

+0

Sí, lo es ... pero también es específico de Rails3 ... y esta pregunta fue formulada hace algún tiempo. –

Cuestiones relacionadas