2010-09-26 15 views
6

¿Hay un mejor enfoque consensuado para implementar roles de usuario cuando se utilizan rutas de recursos RESTful?Estructura de aplicación para recursos RESTful basados ​​en roles

Decir que tengo los siguientes recursos:

User has_many Tickets 
Event has_many Tickets 
Ticket belongs_to Person, Event 

y luego decir que tengo más de dos tipos de usuarios: los clientes y agentes. Ambos iniciarán sesión en el sistema, pero con acceso a diferentes recursos y funcionalidad en función de sus funciones. Por ejemplo:

los clientes pueden acceder a:

  • índice de eventos, muestran
  • índice de entradas (con ámbito por el usuario), espectáculo, comprar/crear, retorno/borrar
  • persona crear, mostrar, actualización

Los agentes pueden acceder a:

  • índice de eventos, mostrar, crear, actualizar, eliminar
  • índice de entradas, mostrar, vender/crear, actualizar, reembolso/eliminar
  • Índice persona, demostración, crear, actualizar, eliminar

¿Cuál de las 4 los enfoques generales a continuación serán más limpios y más flexibles?

controladores separados dentro de las carpetas de papel y los recursos en los espacios de nombres, por ejemplo:

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

controladores separados por papel, por ejemplo:

AgentController 
    def sell_ticket, etc 

CustomerController 
    def buy_ticket, etc 

controladores compartidos con acciones separadas cuando sea necesario, por ejemplo:

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 

Acciones compartidas con declaraciones condicionales, p. Ej .:

TicketController 
    def create 
    if @role == :customer 
     #buy ticket 
    elsif @role == :customer 
     #sell ticket 
    end 
    end 

Respuesta

-1

Si utiliza el mismo modelo para los tickets de clientes y agentes, no debería haber una gran diferencia entre cómo se manejan en el controlador. Por lo tanto, crear acción será siempre así:

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

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

Pero sus puntos de vista se pueden personalizar simplemente:

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

El modelo no tiene conocimiento del usuario que se ha autenticado. Eso generalmente es administrado por el controlador. Además, OP está preguntando sobre la mejor manera de manejar la seguridad. Esto no se puede personalizar en vistas. ¿Qué hay de las conexiones API? ¿Cómo se aplica la seguridad para diferentes roles de usuario allí? No desea repetir el código, por lo que debe estar en un lugar central, es decir: controlador. Entonces, la pregunta es, ¿cómo puede administrar su controlador de forma sensata para agregar este tipo de control sobre los roles y permisos de los usuarios? –

6

se recomienda usar una combinación de las dos últimas implementaciones propuestas. Se adhieren a la representación RESTful, ponen la autorización en el nivel apropiado (controladores) y es una implementación escalable.

REST es, esencialmente, aproximadamente accessing nouns with verbs. Por lo tanto, desea que los agentes y los clientes realicen acciones (verbos) en relación con los tickets, los usuarios y los eventos (sustantivos). Para representar con precisión estos nombres, debe tener un controlador para cada uno. Luego, los clientes pueden identificar el recurso que están buscando mediante la URL, http://example.com/events/22.Desde aquí se puede utilizar el enrutamiento de Rails para representar contexto para varios recursos, es decir http://example.com/events/22/tickets haciendo algo como:

resource :events do 
    resource :tickets 
end 

Al adherirse a una arquitectura REST, que está comprando en el end to end principle. El paradigma para representar objetos debe ser el único responsable de eso. No debería intentar autenticarse. Ese no es su trabajo. La autorización debería ocurrir en los controladores. Recomiendo encarecidamente buscar gemas como CanCan o Declarative Authorization que configuren todo esto para usted.

Finalmente, este modelo escalable. Al mantener la autorización separada de la representación de sus recursos, solo debe usarla si la necesita. Esto mantiene su aplicación ligera, flexible y simple.

0

Si bien ambos se ocupan de crear Tickets, la venta del Agente/Ticket frente a la compra del Cliente/Ticket parece ser lo suficientemente diferente para mí que deberían separarse. Finalmente, podrían divergir aún más, ya que se utilizan de manera diferente desde el principio.

Es posible que se compartan la funcionalidad del controlador, ya sea con módulos o heredando de un controlador padre común:

module TicketsControllersCommom 
    # common helper methods 
end 

class TicketsController < ApplicationController 
    include TicketsControllersCommom 
    # actions 
end 

class AgentTicketsController < ApplicationController 
    include TicketsControllersCommom 
    # actions 
end 

podría tratar las partes de agente como una especie de sección de administración, con las partes de los clientes siendo el por defecto:

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

O, si usted tiene un montón de cosas de tipo de administración, como si los agentes manejan los eventos, así, puede namespace toda una sección:

/agent/events/xx/tickets 
/agent/events/xx/edit 
# etc. 
Cuestiones relacionadas