Forum: Italian Ruby user group Gestione ruoli utenti e controllers

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Serafino P. (Guest)
on 2009-03-26 15:08
Salve a tutti,

sto creando un'applicazione web con rails che comprende un sistema di
gestione ruoli per gli utenti, ma ho qualche dubbio rispetto alla
gestione dei ruoli e l'architettura dell'applicazione.

Al momento gestisco 3 tipi di utenti: Amministratore > Capo Area >
Impiegato , dall'utente con privilegi maggiori fino a quello con
privilegi minimi.

Fin qui nessun problema, riesco a bloccare determinate azioni o interi
controller rispetto al ruolo. Quello che non riesco a strutturare in
modo pulito sono le situazioni dove piu utenti hanno accesso alla stessa
azione, ma devono vedere dati (estratti dal db) differenti.

Esempio:
Un Impiegato ha dei Documenti, nell'azione index del controller
documents dovrei mostrare tutti i SUOI documenti. Un capo area ha
accesso alla stessa azione dello stesso controller, ma vedere tutti i
documenti di TUTTI gli impiegati, un find(:all) in pratica.

Vorrei evitare condizioni nei controller in queste situazioni del tipo:
se sei capo area, fai un find(:all), se sei Impiegato fai un find solo
sui documenti dell'utente ecc...

Mi piacerebbe avere qualche input dalla community per capire come voi
risolvereste la cosa.

Grazie in anticipo!
Alessandro S. (Guest)
on 2009-03-26 21:59
Serafino P. wrote:
> Salve a tutti,
>
> sto creando un'applicazione web con rails che comprende un sistema di
> gestione ruoli per gli utenti, ma ho qualche dubbio rispetto alla
> gestione dei ruoli e l'architettura dell'applicazione.
>
> Al momento gestisco 3 tipi di utenti: Amministratore > Capo Area >
> Impiegato , dall'utente con privilegi maggiori fino a quello con
> privilegi minimi.
>
> Fin qui nessun problema, riesco a bloccare determinate azioni o interi
> controller rispetto al ruolo. Quello che non riesco a strutturare in
> modo pulito sono le situazioni dove piu utenti hanno accesso alla stessa
> azione, ma devono vedere dati (estratti dal db) differenti.
>
> Esempio:
> Un Impiegato ha dei Documenti, nell'azione index del controller
> documents dovrei mostrare tutti i SUOI documenti. Un capo area ha
> accesso alla stessa azione dello stesso controller, ma vedere tutti i
> documenti di TUTTI gli impiegati, un find(:all) in pratica.
>
> Vorrei evitare condizioni nei controller in queste situazioni del tipo:
> se sei capo area, fai un find(:all), se sei Impiegato fai un find solo
> sui documenti dell'utente ecc...
>
> Mi piacerebbe avere qualche input dalla community per capire come voi
> risolvereste la cosa.
>
> Grazie in anticipo!

l'ultima volta che ho fatto una cosa simile ho fatto così :

Riscrivi il metodo find e fai in modo che aggiunga delle conditions in
base all'utente corrente in questo modo quando fai ad esempio
Documents.find(:all) la find lo riscrive mettendo ad es
Document.find(:all, :conditions => { :user_id => 1 })
Carlo P. (Guest)
on 2009-03-26 22:55
(Received via mailing list)
Oppure (supponendo che il metodo current_user restituisca l'utente
corrente):
  u = current_user
  user_documents = u.documents.find(:all)

Il 26 marzo 2009 20.59, Alessandro S. <removed_email_address@domain.invalid> ha
scritto:
>>
>>
>
>
--
Carlo P.
email: removed_email_address@domain.invalid
twitter: @carlopecchia
Pietro G. (Guest)
on 2009-03-26 22:57
(Received via mailing list)
Il 26 marzo 2009 14.08, Serafino P. <removed_email_address@domain.invalid> ha
scritto:
> Vorrei evitare condizioni nei controller in queste situazioni del tipo:
> se sei capo area, fai un find(:all), se sei Impiegato fai un find solo
> sui documenti dell'utente ecc...

in una situazione simile, appunto per non rendere illeggibili i
controller né le view, io ho optato per una certa separazione: ho
definito in User dei metodi tipo may_create_documents?,
may_edit_document?(doc), etc., da usare nelle view per scegliere quali
link mostrare e nei controller per decidere se eseguire un'azione:

# DocumentController.rb
def edit
  @document = Document.find(params[:id])
  if current_user.may_edit_document? @document
    ...
  else
  ...

# view.rb

<% if current_user.may_edit_document? @document %>
  <%= link_to "edit", ... %>
<% end %>

per filtrare gli oggetti ho invece creato dei named_scope, tipo:

named_scope :visible_by, lambda { |user| user.admin? ? {} : {:user_id
=> user.id} }

così nel controller scrivo:

@documents = Document.visible_by(current_user).paginate ...

(Quando poi i metodi in User sono diventati troppi, li ho spostati in
un modulo Permissions incluso da User.)


credo che definire un named_scope sia una soluzione preferibile al
ridefinire find, perché così, leggendo il controller, si capisce
chiaramente l'intenzione del codice, mentre se si ridefinisce find,
ciò non risulta evidente dal codice del controller, e si corre il
rischio di incappare in bug inspiegabili, specie a distanza di tempo.


pietro
Serafino P. (Guest)
on 2009-03-26 23:31
Grazie a tutti,mi sembrano tutti suggerimaneti validi. Alla fine,
analizzando meglio la situazione penso che opterò per una soluzione
leggermente diversa, dato che in diversi casi non cambia solo la query
ma anche quasi comletamente la view e altro codice del controller.

In linea di massima per i casi semplici in cui cambia effettivamente
solo la query, seguo i vostri consigli, e tengo un unico controller per
tutti gli utenti, mentre per il resto creo un namespace diverso per ogni
utente contenente un controller ad hoc, mi sembra la soluzione migliore
per mantenere flessibilità e pulizia.
This topic is locked and can not be replied to.