2011-06-29 38 views
3

我的应用程序是一个表单生成器:定义表单,然后以通常的CRUD方式呈现激活的表单。激活表单的过程触发FormManager创建主Form对象的子类(我使用ActiveRecord中的STI创建type的子类,使用Object.const_set())。活性形式可以停用,这涉及到杀死子类定义(使用Object.const_send(:remove...)如何创建应用程序范围对象

我只需要 FormManager我的应用程序对象。什么是最好的方式去做这件事?我目前使用的一类变量ApplicationController实现这个...它的工作原理,但似乎有点笨重:

require 'lib/form_manager.rb' 

class ApplicationController < ActionController::Base 
    helper :all # include all helpers, all the time 
    attr_reader :registry 

    protect_from_forgery 

    @@registry = FormManager.new 
end 

我运行红宝石1.8.7,轨2.3.11发展模式 - 我是看到这只是因为我处于开发模式?

+2

你可能想让你的F ormManager是一个单例。 http://dalibornasevic.com/posts/9-ruby-singleton-pattern-again – Pavling

+0

@Pavling:为什么评论而不是答案?我会给你+1,因为这是个好主意,但有评论我不能给你点 – MBO

+0

@Pavling,谢谢你,非常有用的文章 – smcphill

回答

8

不,它只是这样工作。 Rails有请求响应模型,并为每个请求创建一些控制器的新实例(可能继承自您的ApplicationController),设置一些请求参数,然后触发您的操作方法。如果你想在请求之间共享状态,你需要把它放在控制器之外,例如,当你的应用程序由服务器启动时,它被初始化为常量(它只是Ruby)。

如果您需要注册的单个实例,只是把它放在 “配置/初始化/ registry.rb”:

require 'lib/form_manager.rb' 

REGISTRY = FormManager.new 

Template.all(:conditions => { :is_active => false }).each do |t| 
    REGISTRY.loadForm(t.id) 
end 

,然后在ApplicationController中:

class ApplicationController < ActionController::Base 
    helper :all # include all helpers, all the time 

    protect_from_forgery 

    def registry 
    REGISTRY 
    end 
end 
+0

宾果 - 感谢您的澄清和解决方案! – smcphill

+0

请求之间的共享状态是一个棘手的问题。像这样的全局对象可能在开发时工作,但是当部署应用程序时,几乎肯定会有多个进程同时运行。这意味着不止一个FormManager将存在,每个进程中都有一个。每个FormManager都不会意识到其他人做了什么,所以它在整个应用程序中并不是真正的全局。 –

+0

@Jeff当然不是,谢谢你指出。它是请求之间但在相同应用程序中的全局对象。所以它不应该用于与所有应用程序实例共享状态。为此,最好的是一些pub/sub机制。但这是不同的故事。 – MBO

1

是的,将为每个请求创建一个新的ApplicationController对象(您可以通过添加一个运行“puts self.id”来检查控制器对象的对象ID的before_filter来检查该对象。每个请求)。

为什么你想跨请求单个对象?你想达到什么目的?

+0

感谢您的澄清。我通过将'registry'变成一个类变量来获得期望的效果,但是我觉得这样做很肮脏。即将更新回答第二个问题 – smcphill

相关问题