Ruby on rails 在Rails初始值设定项中将模块包含到ruby类中
在Rails中的初始值设定项中,我试图在Rails模型中包含一个模块Ruby on rails 在Rails初始值设定项中将模块包含到ruby类中,ruby-on-rails,ruby,module,include,actiondispatch,Ruby On Rails,Ruby,Module,Include,Actiondispatch,在Rails中的初始值设定项中,我试图在Rails模型中包含一个模块 User.send :include, Something 这适用于第一个请求,但不适用于第二个/第三个/等,因为rails模型重新加载。我尝试使用ActionDispatch::Callbacks。为了准备(,我使用的是Rails 3.0.9) 但是,当我尝试在第二个/第三个/etc.请求中调用模块中定义的方法时,我不断从用户实例中得到一个NoMethod错误 我的问题是:有没有一种方法可以可靠地将模块包含到初始值设定项中
User.send :include, Something
这适用于第一个请求,但不适用于第二个/第三个/等,因为rails模型重新加载。我尝试使用ActionDispatch::Callbacks。为了准备(,我使用的是Rails 3.0.9)
但是,当我尝试在第二个/第三个/etc.请求中调用模块中定义的方法时,我不断从用户实例中得到一个NoMethod错误
我的问题是:有没有一种方法可以可靠地将模块包含到初始值设定项中的Rails模型中,而不会出现任何开发上的奇怪现象
更新:不可能
显然,没有中间件这是不可能的。如果您不同意,请在下面添加一个答案。对于我的用例来说,这不是一个可接受的解决方案,所以我甚至没有尝试过。祝你好运
编辑:更新的调试信息
我在玩ActionDispatch::Callbacks。为了准备更多的,当我把这个放在我的初始值设定项中时,我注意到了一些奇怪的事情:
ActionDispatch::Callbacks.to_prepare do
puts "to_prepare ==:#{User.object_id}"
end
这个在我的控制器里
puts "controller ==:#{User.object_id}"
在第一次请求时,我得到以下信息:
to_prepare ==: 2297196200
controller ==: 2297196200
to_prepare ==: 2297196200
to_prepare ==: 2324202920
to_prepare ==: 2318560780
在第二个请求中,我得到了以下信息:
to_prepare ==: 2326823900
controller ==: 2326823900
to_prepare ==: 2317901920
to_prepare ==: 2326746040
to_prepare ==: 2314369160
我注意到的第一件事是多次打电话给_prepare,这很奇怪。我注意到的第二件事是在第一个请求中(有效),在调用控制器之前和之后直接调用的对象_id是相同的,并且它们不在任何后续调用中。如果有人能够解释为什么会发生这种情况以及如何避免这种情况,我们将不胜感激。在初始化后使用配置是否有帮助?这是一个特定于开发环境的问题,因为类正在重新加载
几乎可以肯定的一件事是通过中间件注入您的模块,尽管很难知道这是否适合您所做的任何事情
class AddYourModuleMiddleware
def initialize(app)
@app = app
end
def call(env)
User.send(:include, YourModule) unless User < YourModule
@app.call(env)
end
end
class AddYourModuleMiddleware
def初始化(应用程序)
@app=app
结束
def呼叫(环境)
User.send(:include,YourModule),除非User
使用config.middleware.use AddYourModuleMiddleware
将其添加到中间件链中,或者将use addyourmidleware
放在应用程序控制器
的开始处。初始化后是否使用配置?这是一个特定于开发环境的问题,因为类正在重新加载
几乎可以肯定的一件事是通过中间件注入您的模块,尽管很难知道这是否适合您所做的任何事情
class AddYourModuleMiddleware
def initialize(app)
@app = app
end
def call(env)
User.send(:include, YourModule) unless User < YourModule
@app.call(env)
end
end
class AddYourModuleMiddleware
def初始化(应用程序)
@app=app
结束
def呼叫(环境)
User.send(:include,YourModule),除非User
使用config.middleware.use AddYourModuleMiddleware
将其添加到中间件链中,或者将use addyourmidleware
放置在ApplicationController
的开头,是否有理由在初始值设定项中执行此操作?在用户模型中包含一些在任何环境下都能工作的东西。@bandito,这是我问题的简化版本。这是一个需要在初始值设定项中完成的原因。。。这里有点太长了。简而言之,我将把它烘焙成一个gem,一个类需要知道实现接口的其他类。这不是我第一次想做这类事情,却被Rails开发模型重新加载所阻碍。Rails在开发过程中的请求之间重新加载控制器和模型(以及其他东西)。第一个请求不太可能与所有后续请求相同。我不知道内部是什么(您必须阅读github上的源代码),但这就是为什么您会看到对象id以这种方式变化的原因。这也是为什么我认为初始值设定项是不可能的,因为它不是按请求运行的。如果您正在编写gem,您可能可以使用railties注入中间件,而不考虑用户。是否有理由在初始值设定项中执行此操作?在用户模型中包含一些在任何环境下都能工作的东西。@bandito,这是我问题的简化版本。这是一个需要在初始值设定项中完成的原因。。。这里有点太长了。简而言之,我将把它烘焙成一个gem,一个类需要知道实现接口的其他类。这不是我第一次想做这类事情,却被Rails开发模型重新加载所阻碍。Rails在开发过程中的请求之间重新加载控制器和模型(以及其他东西)。第一个请求不太可能与所有后续请求相同。我不知道内部是什么(您必须阅读github上的源代码),但这就是为什么您会看到对象id以这种方式变化的原因。这也是为什么我认为初始值设定项是不可能的,因为它不是按请求运行的。如果您正在编写gem,您可能可以使用railties注入中间件,而不必担心用户。您尝试过这个吗?控制器和中间件中的User.object\u id
是否不同?虽然这是一个有趣的建议,但应该有一种方法可以做到这一点,而不需要我将中间件放在我的gem中。我还没有尝试过,不,对不起。。。但我认为99%的情况下,它会起作用,因为我们使用中间件来完成准备请求所需的其他工作。您尝试过这个吗?控制器和中间件中的User.object\u id
是否不同?虽然这是一个有趣的建议,但应该有一种方法可以做到这一点,而不需要我将中间件放在我的gem中。我还没有尝试过,不,对不起。。。但我认为99%的情况下,它会起作用,因为我们使用中间件来完成准备请求所需的其他工作。