首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails中的RESTful DCI上下文

Rails中的RESTful DCI上下文
EN

Stack Overflow用户
提问于 2012-02-02 14:52:42
回答 1查看 1.4K关注 0票数 12

我第一次通过this blog post了解了this blog post (DCI)。对这个概念着迷,我努力将其构建到我的下一个Rails应用程序中。因为DCI是与MVC协同工作的,所以我认为同时制作API RESTful并不是太困难。因此,我创建了一个RESTful资源,Report,并使用各种上下文对其进行扩展。我在Rails中实现上下文的方式是为扩展控制器操作的模块创建一个目录/app/contexts/。所以我的reports_controller.rb是这样的:

代码语言:javascript
复制
class ReportsController < ApplicationController
  before_filter :only => :new do |c|
    c.switch_context("submission")
  end

  # GET /reports
  def index
    @context.report_list
  end

  # GET /reports/1
  def show
    @context.display_report
  end

  # GET /reports/new
  def new
    @context.new_report
  end

  # GET /reports/1/edit
  def edit
    @context.edit_report
  end

  # POST /reports
  def create
    @context.create_report
  end

  def update
    @context.update_report
  end

  # DELETE /reports/1
  def destroy
    @context.destroy_report
  end

  protected

  def switch_context(context_name)
    session[:context] = context_name
    context = session[:context].camelize.constantize
    @context ||= self.extend context
  end
end

application_controller.rb中,我用一个before_filter设置上下文

代码语言:javascript
复制
class ApplicationController < ActionController::Base
  before_filter :contextualize
  protect_from_forgery

  protected

  # Sets the context of both current_user and self
  # by extending with /app/roles/role_name
  # and /app/contexts/context_name respectively
  def contextualize
    # Extend self (ActionController::Base) with context
    if session[:context]
      context_class = session[:context].camelize.constantize
      if current_user.allowed_contexts.include?(context_class)
        context_class = current_user.context if context_class == Visiting
      else
        context_class = Visiting
      end
    else
      context_class = current_user.context
    end
    @context ||= self.extend context_class
  end
end

注意,除了控制器上下文之外,我还使用一个current_user扩展了Role

下面是它的工作原理:

用户登录。用户的角色是RegisteredUser.

  • RegisteredUser's,默认上下文是Search (如在/app/roles/registered_user.rb).

  • Inside中定义的Search上下文,用户只能查看已发布的报表。

  • 用户按下“创建新报告”按钮,将上下文更改为Submission并存储在current_user的会话中。

  • 用户然后继续通过多步表单提交报表。

  • 每次用户通过/app/contexts/submission.rb上下文处理的表单保存报表。h 233g 234

还有其他几种情况(评论、社论等)。以及角色(合著者、编辑等)。

到目前为止,这一方法在很大程度上运作良好。但存在一个缺陷:当用户打开多个浏览器窗口并在其中一个窗口中更改上下文时,其他所有窗口都将处于错误的上下文中。如果用户处于多步表单的中间,然后在Search上下文中打开窗口,则可能会出现问题。当他切换回表单并点击"Next“时,控制器将执行由Search上下文而不是Submission上下文定义的操作。

有两种可能的解决方法,我可以想到:

  1. 命名空间使用上下文名称对Report资源进行空间设置。因此,用户将访问网址,如/search/reports/submission/reports/1。在我看来,这并不是RESTful,我更愿意保持URL的干净,就像RESTful一样--隐藏字段中的上下文名称。这种方法要求开发人员记住将隐藏字段放在站点上的每个表单中,并且它不适用于GET请求。

是否有其他方法可以解决这个问题,或者更好的整体实现?

我知道this project,但它对我们的需求来说太有限了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-02-18 14:11:49

如果您想要允许多个上下文,那么很明显,您必须将确定当前上下文的信息放在一些不能在制表符之间共享的存储中。会话(在Rack/Rails中实现)使用cookie,cookie在选项卡之间共享。

只要把上下文放到一些不共享的东西上就行了。context=viewer URL参数如何?

说到休息,我认为在不同的情况下,资源是否相同是有争议的。可以说,“访问”用户的报告与“管理”用户的报告不同。在这种情况下,RESTy方法可能会命名为请求(这再次将上下文放入URL),例如/ requests /reports/1 vs /administering/reports/1。

将上下文放入URL的第三种方法是将其作为域名的一部分使用。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9114393

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档