Ree*_*Law 12 ruby rest ruby-on-rails dci
我首先通过这篇博文了解了数据,上下文和交互(DCI).着迷于这个概念,我努力将其构建到我的下一个Rails应用程序中.由于DCI与MVC协同工作,我认为同时使API RESTful不会太难.所以我创建了一个RESTful资源,并使用各种上下文扩展它.我在Rails中实现上下文的方法是为扩展控制器操作的模块创建一个目录.所以我看起来像这样:Report
/app/contexts/
reports_controller.rb
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
Run Code Online (Sandbox Code Playgroud)
在application_controller.rb
我设置上下文中before_filter
:
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
Run Code Online (Sandbox Code Playgroud)
注意我除了控制器上下文之外还扩展current_user
了一个Role
.
以下是它的工作原理:
RegisteredUser
.RegisteredUser
默认上下文是Search
(如中所定义/app/roles/registered_user.rb
).Search
上下文中,用户只能查看已发布的报告.Submission
并存储在current_user
会话中./app/contexts/submission.rb
上下文都会处理该操作.还有其他几个背景(评论,编辑等)和角色(共同作者,编辑等).
到目前为止,这种方法在大多数情况下运作良好.但是有一个缺陷:当用户打开多个浏览器窗口并更改其中一个窗口中的上下文时,所有其他窗口都将处于错误的上下文中.如果用户处于多步骤表单的中间,然后在Search
上下文中打开一个窗口,则这可能是一个问题.当他切换回窗体并点击"下一步"时,控制器将执行Search
上下文而不是Submission
上下文定义的操作.
我可以想到有两种可能的方法:
Report
使用上下文名称命名空间资源.因此用户可以访问诸如/search/reports
和之类的URL /submission/reports/1
.这对我来说似乎并不RESTful,我宁愿保持URL尽可能干净.有没有其他方法可以解决这个问题,或者更好的整体实现?
我知道这个项目,但它对我们的需求来说太有限了.
如果您想允许多个上下文,那么显然您必须将确定当前上下文的信息放置在选项卡之间不共享的某个存储中。在 Rack/Rails 中实现的会话使用 cookie,并且 cookie 在选项卡之间共享。
只需将上下文放入不共享的内容中即可。context=viewer URL 参数怎么样?
谈到 REST,我认为资源在不同上下文中是否相同是有争议的。有人可能会争辩说,“访问”用户的报告与“管理”用户的报告不同。在这种情况下,RESTy 方法可能会对请求命名空间(再次将上下文放入 URL 中),例如 /visiting/reports/1 与 /administering/reports/1。
将上下文放入 URL 的第三种方法是将其用作域名的一部分。
归档时间: |
|
查看次数: |
1352 次 |
最近记录: |