Ho un'app per rotaie con un modello utente, che è in grado di avere diversi ruoli. Ho implementato questo utilizzando una maschera di bit come questo:Permette solo determinati valori possibili nei parametri Rails Strong
class User < ActiveRecord::Base
DEFAULT_ROLES = %w[developer entrepreneur]
ROLES = ['admin', 'entrepreneur', 'developer']
def has_role?(role)
roles.include?(role.to_s)
end
def is?(role)
has_role?(role)
end
def roles=(roles)
self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+)
end
def roles
ROLES.reject do |r|
((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero?
end
end
end
Nella pagina di registrazione per l'applicazione, voglio agli utenti di scegliere se si tratta di un 'imprenditore' o un 'sviluppatore'. Tuttavia, voglio assicurarmi che non siano in grado di assegnare a se stessi (o a nessun altro) nessun altro ruolo, a meno che non siano già amministratori.
Il mio primo pensiero è stato quello di fare questo nel metodo roles=
da changin per assomigliare
def roles=(roles)
unless current_user.is?(:admin)
validates_inclusion_of roles, :in => DEFAULT_ROLES
end
self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+)
end
Tuttavia, come ho scoperto, non è possibile accedere current_user
dall'interno di un modello (che immagino marche senso se ci pensate ...)
Il mio prossimo tentativo era di vedere se potevo farlo usando Strong Parameters.
mi aspettavo che sarebbe simile a questa (sto usando ideare, ignorando l'RegistrationsController)
class RegistrationsController < Devise::RegistrationsController
private
def sign_up_params
if (user_signed_in?) && (current_user.is?(:admin))
params.require(:user).permit(:name, :school, :email, :password, :password_confirmation, {roles: User::ROLES})
else
params.require(:user).permit(:name, :school, :email, :password, :password_confirmation, {roles: User::DEFAULT_ROLES})
end
end
def account_update_params
if (user_signed_in?) && (current_user.is?(:admin))
params.require(:user).permit(:name, :school, :email, :password, :password_confirmation, :current_password, :about_me, {roles: User::ROLES})
else
params.require(:user).permit(:name, :school, :email, :password, :password_confirmation, :current_password)
end
end
end
Tuttavia, quando ho provato, ho ottenuto questo: che mi fa pensare che' Mi fraintendimento di come Strong Parameters funzioni davvero.
È possibile limitare i valori che un utente può immettere per un determinato campo in base al ruolo degli utenti con i parametri forti? Se no, c'è un modo diverso per farlo?
Dovrebbe essere definito come convalida del modello. Un parametro forte è per filtrare le chiavi param, non i valori. – kengo
@kengo - Come posso convalidarlo nel modello se non riesco ad accedere al ruolo utente corrente? (poiché gli amministratori potrebbero modificare altri utenti, non solo loro stessi) – Ephraim
Non è possibile definire un parametro forte come before_action. Utilizzare in questo modo nel metodo di creazione o aggiornamento. Account.new (account_update_params) – kengo