2010-09-26 13 views
6

Esiste un approccio ottimale per l'implementazione dei ruoli utente quando si utilizzano RESTful resource route?Struttura dell'app per risorse RESTful basate su ruoli

Dire che ho le seguenti risorse:

User has_many Tickets 
Event has_many Tickets 
Ticket belongs_to Person, Event 

e poi dire ulteriormente Ho due tipi di utenti: i clienti e gli agenti. Entrambi si collegheranno al sistema, ma con accesso alle risorse e funzionalità diverse in base ai loro ruoli. Per esempio:

I clienti possono accedere:

  • indice evento, esposizione
  • indice di biglietteria (ambito dall'utente), spettacolo, comprare/creare, ritorno/cancellare
  • persona di creare, spettacolo, aggiornamento

agenti possono accedere a:

  • indice di evento, esposizione, creare, aggiornare, cancellare
  • indice di biglietteria, spettacolo, vendere/creare, aggiornare il rimborso/cancellazione
  • indice di una persona, spettacolo, creare, aggiornare, cancellare

Quale dei 4 gli approcci generali di seguito saranno più puliti e più flessibili?

controller separati all'interno di cartelle di ruoli e risorse in spazi dei nomi, come ad esempio:

namespace "agent" do 
    resources :events, :tickets, :people 
end 
namespace "customer" do 
    resources :events, :tickets, :people 
end 

controller separati per funzione, per esempio:

AgentController 
    def sell_ticket, etc 

CustomerController 
    def buy_ticket, etc 

regolatori condivisi con azioni separate dove necessario, ad esempio:

TicketController 
    before_filter :customer_access, :only => :buy 
    before_filter :agent_access, :except => :buy 

    def buy #accessed by customer to create ticket 

    def sell #accessed by agent to create ticket 

Azioni condivise con istruzioni condizionali, ad es .:

risposta

-1

Se si utilizza lo stesso modello per i ticket cliente e agente, non ci dovrebbe essere alcuna differenza sostanziale tra il modo in cui vengono gestiti nel controller. Quindi, creare l'azione sarà sempre così:

@ticket = Ticket.new(params[:ticket]) 

if @ticket.save 
    redirect_to @ticket 
else 
    render :action => "new" 
end 

Ma vostri punti di vista può essere semplicemente personalizzati:

<% if customer? %> 
    Customer area. 
<% else %> 
    Agent area. 
<% end %> 
+0

Tuttavia, il modello non è a conoscenza dell'utente che ha effettuato l'autenticazione. Di solito è gestito dal controller. Inoltre, l'OP sta chiedendo il modo migliore per gestire la sicurezza. Questo non può essere personalizzato nelle visualizzazioni. Che mi dici delle connessioni API? Come si applica la sicurezza per i diversi ruoli utente lì? Non si desidera ripetere il codice, quindi deve essere in un posto centrale, ad esempio: controller. Quindi la domanda è: come si può gestire il controller con cura per aggiungere questo tipo di controllo sui ruoli e le autorizzazioni degli utenti. –

6

Io suggerirei di usare una combinazione degli ultimi due implementazioni proposte. Aderiscono alla rappresentazione RESTful, mettono l'autorizzazione al livello appropriato (controller) ed è un'implementazione scalabile.

REST è, in sostanza, circa accessing nouns with verbs. Quindi vuoi che Agenti e Clienti eseguano azioni (verbi) in relazione a Ticket, Utenti ed Eventi (nomi). Per rappresentare accuratamente questi nomi dovresti avere un controller per ciascuno. I clienti possono quindi identificare la risorsa che stanno cercando dall'URL, http://example.com/events/22.Da qui è possibile utilizzare il routing di Rails per rappresentare il contesto per varie risorse, vale a dire http://example.com/events/22/tickets facendo qualcosa di simile:

resource :events do 
    resource :tickets 
end 

Aderendo ad un'architettura RESTful, si acquista in end to end principle. Il paradigma per rappresentare gli oggetti deve essere solo responsabile di ciò. Non dovrebbe provare ad autenticare. Non è il suo lavoro. L'autorizzazione dovrebbe avvenire nei controllori. Consiglio vivamente di cercare gemme come CanCan o Declarative Authorization per impostare tutto questo per te.

Infine, questo modello è scalabile. Tenendo l'autorizzazione separata dalla rappresentazione delle tue risorse, devi usarla solo se ne hai bisogno. Ciò mantiene la tua applicazione leggera, flessibile e semplice.

0

Mentre entrambi si occupano della creazione di biglietti, la vendita di agenti/biglietti rispetto all'acquisto cliente/biglietto mi sembra abbastanza diversa da dover essere separati. Alla fine potrebbero ulteriormente divergere dal momento che vengono utilizzati in modo così diverso dall'inizio.

E 'possibile avere condiviso funzionalità del controller sia con moduli o ereditando da un controllore principale comune:

module TicketsControllersCommom 
    # common helper methods 
end 

class TicketsController < ApplicationController 
    include TicketsControllersCommom 
    # actions 
end 

class AgentTicketsController < ApplicationController 
    include TicketsControllersCommom 
    # actions 
end 

Forse trattare le parti agente come una sorta di sezione amministrativa, con le parti del cliente è il predefinito:

/events/xx/tickets # collection 
/events/xx/tickets/xx # member 
# etc. 
/events/xx/agent/tickets # collection 
/events/xx/agent/tickets/xx # member 
# etc. 

Oppure, se si dispone di un sacco di roba admin-tipo, come se gli agenti di gestire gli eventi, così, si può namespace un'intera sezione:

/agent/events/xx/tickets 
/agent/events/xx/edit 
# etc. 
Problemi correlati