这是一个简单的解决方案。
变化:
- 没有需要检查的
USER_KEY
存在。
- 试着在接收器的模块/类上查找常量(在你的情况下它将是控制器)。如果存在,则使用它,否则使用默认模块/类(请参阅下面的默认模块)。
。
module Auth
USER_KEY = "user"
def authorize
user_key = self.class.const_defined?(:USER_KEY) ? self.class::USER_KEY : USER_KEY
user_id = session[user_key]
def
end
说明
你看到的行为是不特定的轨道,而是由于其中红宝石查找常量,如果不通过::
明确范围的(我所说的“默认”以上)。使用“当前执行代码的词法范围”查找常量。这意味着ruby首先在执行代码的模块(或类)中查找常量,然后向外移动到每个连续的封闭模块(或类),直到找到在该范围内定义的常量。
在您的控制器中,您可以拨打authorize
。但是当authorize
正在执行时,当前正在执行的代码是Auth
。所以这是查找常量的地方。如果Auth没有USER_KEY
,但是封闭模块具有它,则将使用封闭模块。例如:
module Outer
USER_KEY = 'outer_key'
module Auth
# code here can access USER_KEY without specifying "Outer::"
# ...
end
end
这方面的一个特别的例子是顶级执行环境,其被视为属于Object
类。
USER_KEY = 'top-level-key'
module Auth
# code here can access the top-level USER_KEY (which is actually Object::USER_KEY)
# ...
end
一个缺陷是定义一个模块或类与作用域运算符(::
):
module Outer
USER_KEY = 'outer_key'
end
module Outer::Auth
# methods here won't be able to use USER_KEY,
# because Outer isn't lexically enclosing Auth.
# ...
end
注意,常数可以大大晚于所述方法被定义定义。当USER_KEY被访问时,查询只发生,所以这个工程太:
module Auth
# don't define USER_KEY yet
# ...
end
# you can't call authorize here or you'll get an uninitialized constant error
Auth::USER_KEY = 'user'
# now you can call authorize.
谢谢詹姆斯,那正是我正在寻找的。 – user204078 2010-04-30 00:57:29