从模块访问会话变量或控制器变量

Posted

技术标签:

【中文标题】从模块访问会话变量或控制器变量【英文标题】:Access session variable or controller variable from module 【发布时间】:2011-12-13 04:52:03 【问题描述】:

使用:Rails 3.0.3

我的网站有这个功能(count calculate.com),它包含很多不同的计算。用户可以通过表格为小数(有效数字)设置自己的变量。首先,我将此变量设置为 configatron 变量,结果证明这是一个坏主意(某些用户所做的更改已传递给所有用户)。

因此,我决定将其设为会话变量,这很有意义,因为用户应该选择自己的十进制值。

现在,在控制器中,我调用一个模块函数,该函数又调用 100 个不同的模块函数,具体取决于 id。

我的问题:

我想在那个模块中访问这个会话变量,结果证明这是不可能的。已经从控制器(通过模型)传递它有点像噩梦,因为它需要为每个函数传递。

所以:

    如何从 lib-catalog 中的模块访问会话变量? 如何从模块访问控制器方法?如果是这样,我可以调用该方法并获取会话变量。

【问题讨论】:

【参考方案1】:

这是一种方法,将您的计算模块混合到控制器中

# application_controller contains a method that wraps your session value
class ApplicationController < ActionController::Base
    protect_from_forgery

    def user_value
        return 5 # really a session value
    end
end

包含您的计算方法的模块需要访问会话,因为您将其混合到控制器中,您可以使用 self 调用 user_value 方法

module CalculationModule  
    def super_cool_calculation
        return self.user_value * 420
    end

    # more calculation methods  
end

注意 self.user_value 调用,该方法未在模块中定义,但您需要在混入的类中定义它

class FooController < ApplicationController
    include CalculationModule

    def show
        @calculation = super_cool_calculation # call calculation module method
    end

# etc...

如果您的任何模型对象还定义了一个 user_value 方法,那么您可以在需要时将计算模块混合到那些对象中,它们可能不会从会话中获取值

其他需要考虑的事情,只需将用户定义的值存储在数据库中而不是会话中,您就可以轻松地从模型或控制器中访问值

【讨论】:

【参考方案2】:

你的意思是 ruby​​ 模块吗?就像在mixin中一样?如果您将其包含在控制器中,则它已经可以访问控制器可以访问的所有内容。只需致电sessionrequestparams 等,一切都会正常工作。

如果您真的需要从系统的某个任意部分获取会话,您可以通过以下方式获取请求:

ActionDispatch::Request.new(ENV)

然后您可以从请求中获取会话。 (请注意,请求实际上是一个变相的单例......如果已经构建了一个新请求,它将不会构建一个新请求)。

【讨论】:

如何从请求中获取会话? 在什么情况下?我一直在使用它(Rails 3.x)。 继承自rack.rubyforge.org/doc/classes/Rack/Request.html#M000254(见api.rubyonrails.org/classes/ActionDispatch/Request.html) 我刚刚在一些模型代码中添加了这一行并刷新了浏览器。你的意思是你使用ActionDispatch::Request.new(ENV) 代码?或者request.session[:whatever],我相信它相当于session[:whatever]【参考方案3】:

听起来您的模型包含模块代码。你真的不想直接从那里使用或访问会话。它打破了 MVC 的目的,Rails 正在尽最大努力阻止你尝试这样的事情。

当您说“我调用一个模块函数,该函数又调用 100 个不同的模块函数,具体取决于 id。”我想看看那段代码。

您最初的想法是正确的...需要将值传递给模型...听起来代码需要稍微干燥一下,这样就不会那么令人头疼.

不看代码就很难给出建议。我陷入了类似的情况并使用动态方法(覆盖 method_missing)来解决问题。

【讨论】:

以上是关于从模块访问会话变量或控制器变量的主要内容,如果未能解决你的问题,请参考以下文章

如何访问控制器中的会话变量

无法访问 Kohana 控制器中的会话变量

如何将一个控制器中的会话变量访问到 SpringMVC 中的另一个控制器?

http协议。会话控制cookie

从视图子视图类中访问控制器变量或方法

销毁会话,但保留一个变量集