基于角色的RESTful资源的应用程序结构

Ed *_*ood 6 ruby-on-rails restful-authentication

在使用RESTful资源路由时,是否存在实现用户角色的最佳共识方法?

说我有以下资源:

User has_many Tickets
Event has_many Tickets
Ticket belongs_to Person, Event
Run Code Online (Sandbox Code Playgroud)

然后进一步说我有两种类型的用户:客户和代理商.两者都将登录到系统,但具有基于其角色的不同资源访问和功能.例如:

客户可以访问:

  • 事件索引,显示
  • 故障单索引(由用户确定),显示,购买/创建,返回/删除
  • 人创造,展示,更新

代理可以访问:

  • 事件索引,显示,创建,更新,删除
  • 票务索引,显示,销售/创建,更新,退款/删除
  • 人员索引,显示,创建,更新,删除

以下4种一般方法中哪一种更清洁,更灵活?

角色文件夹中的独立控制器和命名空间中的资源,例如:

namespace "agent" do
  resources :events, :tickets, :people
end
namespace "customer" do
  resources :events, :tickets, :people
end
Run Code Online (Sandbox Code Playgroud)

按角色分隔控制器,例如:

AgentController
  def sell_ticket, etc

CustomerController
  def buy_ticket, etc
Run Code Online (Sandbox Code Playgroud)

共享控制器在需要时具有单独的操作,例如:

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
Run Code Online (Sandbox Code Playgroud)

与条件语句共享的操作,例如:

TicketController
  def create
    if @role == :customer
      #buy ticket
    elsif @role == :customer
      #sell ticket
    end
  end
Run Code Online (Sandbox Code Playgroud)

vri*_*h88 6

我建议使用最后两个提议的实现的组合.它们遵循RESTful表示,将授权放在适当的级别(控制器),并且它是可扩展的实现.

REST本质上是关于使用动词访问名词.因此,您希望代理和客户执行与故障单,用户和事件(名词)相关的操作(动词).为了准确地表示这些名词,你应该为每个名词配备一个控制器.然后,客户可以通过URL识别他们正在查找的资源http://example.com/events/22.从这里,您可以使用Rails的路由来表示各种资源的上下文,即http://example.com/events/22/tickets通过执行以下操作:

resource :events do
  resource :tickets
end
Run Code Online (Sandbox Code Playgroud)

通过坚持RESTful架构,您将购买端到端原则.表示对象的范例只需要对此负责.它不应该尝试进行身份验证.那不是它的工作.授权应该在控制器中进行.我强烈建议您查看CanCan声明授权等宝石,为您设置所有这些.

最后,这个模型可扩展.通过将授权与资源的表示分开,您只需在需要时使用它.这使您的应用程序轻松,灵活,简单.


Sim*_*tsa -1

如果您对客户和代理票证使用相同的模型,则它们在控制器中的处理方式应该没有重大差异。所以,创建动作总是这样的:

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

if @ticket.save
  redirect_to @ticket
else
  render :action => "new"
end
Run Code Online (Sandbox Code Playgroud)

但您的视图可以简单地定制:

<% if customer? %>
  Customer area.
<% else %>
  Agent area.
<% end %>
Run Code Online (Sandbox Code Playgroud)