openSUSE:Appliances events workshop Nuremberg 2010 projects railsification

跳转到:导航搜索

团队

  • Michael Calmer
  • Daniel Schmidt
  • Lucas Ocilka
  • Vladislav Gorobets
  • Gabi Mohr
  • Jozef Uhliarik
  • Cristoph Thiel

Railsify the registration controller

此任务的目标是清理注册控制器。这意味着将代码块移动到它们应该在的位置,遵循 Rails 的约定。Rails 定义了严格的模型、视图和控制器分离。允许在单独的文件中使用辅助方法,但直接处理模型数据的的方法应该位于同一个文件中,而创建输出数据的代码必须位于视图中。

SLMS 中注册控制器 railsification 的初步结果

1. 我们已经修改了使用视图构建 XML 文件的示例

webapp/config/environment.rb
 config.gem 'builder'   added
webapp/app/controllers/registration_controller.rb
 list_subscriptions
 render 'list_subscriptions', :format => :xml
 instead of
 xml = build_listsubscriptions(subscr_list, result[:auth_user])
 render :xml => xml

已添加文件

webapp/app/views/registration/list_subscriptions.builder 

例如,registration_controller_helper.rb 中的 build_listsubscriptions 不再需要。

2. 我们将功能从 registration_controller.rb 移动到模型 customer。这些文件已更改

webapp/app/controllers/registration_controller.rb
list_subscriptions
functionality to build the list of subscriptions removed and moved to customer
webapp/app/models/customer.rb
def smt_subscriptions    added

Railsifying webservice routes

注册(如 NCC 定义)使用静态路径进行所有查询和操作,或将特殊函数作为参数与所有其他注册数据一起传递。这不符合 Rails 的风格,因为 Rails 定义查询路径应该看起来像:example.com/controller/action

不可能更改所有已安装的系统以更新到新的查询路径,也不可行在 NCC 中实现这些更改。为了在内部 railsify 注册,我们引入了一个 Rails 中间件,它将当前的请求映射到类似 Rails 的路由。中间件插入在 Web 服务器和 Rails 应用程序(在本例中为 SLMS)之间,可以完全劫持请求,发送自己的响应,或者只是修改请求并使用更改后的请求调用底层应用程序。在我们的例子中,我们只是解析参数数据并重写请求,以便映射现有的注册控制器及其(待定义)操作。因此,在 SLMS 内部,我们可以使用所有 Rails 约定,并且所有请求看起来都像标准的 Rails 请求,而对于外部 SLMS 仍然表现得像一个正常的注册服务器。


将请求转换为注册控制器的中间件如下所示

class RegistrationTranslator
  ALLOWED_COMMANDS = %w[ register listparams listproducts de-register listregistrations listsubscriptions bulkop regdata ]

  def initialize(app)
    @app = app
  end

  def call(env)
    if env['PATH_INFO'] == '/center/regsvc' then
      reg = /command=([a-zA-Z0-9\-_]+)/
      action = env['QUERY_STRING'].scan(reg).flatten.first

      if ALLOWED_COMMANDS.include? action then
        env['PATH_INFO'].sub!('/center/regsvc', "/registration/#{ action }")
        env['REQUEST_URI'] = "#{ env['PATH_INFO'] }?#{ env['QUERY_STRING'] }"
      end
    end

    return @app.call(env)
  end
end

要使用此中间件,需要在environment.rb中插入它,如下所示(在config.gem部分之后)

 config.middleware.use "RegistrationTranslator"

现在运行后,中间件已经转换了请求。但是 SLMS 会渲染一个错误,因为它还不知道新的路由。我们使用routes.rb中的map.connect命令映射路由

 map.connect '/registration/:action', :controller => 'registration'

通过所有这些设置,SLMS 中的注册将从外部静态路径透明地映射到内部类似 Rails 的路由。仍然需要将允许注册的所有操作作为自己的函数公开。这是已经开始的清理工作的一部分(见上文)。

我们都学到了很多关于 Rails 约定、模型、视图和控制器的分离、中间件、请求模型,并认为将我们的更改合并到 SLMS 的主分支中是有价值的,以便在有时间的情况下允许未来的清理会话。这样,维护可以由习惯于 Rails 约定的 Rails 开发人员完成。如果未包含中间件,则无法正确清理控制器中的方法。