我们的应用程序使用了许多环境,因此我们可以在不破坏事物的情况下试验设置。在典型的控制器操作中,我有类似的东西:
def some_action
...
if @foo.development_mode == 'Production'
@settings = SomeHelper::Production.lan(bar)
elsif @foo.development_mode == 'Beta'
@settings = SomeHelper::Beta.lan(nas)
elsif @foo.development_mode == 'Experimental'
@settings = SomeHelper::Experimental.lan(nas)
end
...
end
由于我们有很多这些,我想我可以尝试用这样的东西来干涸:
@settings = "SomeHelper::#{@foo.development_mode}.lan(bar)"
这显然不起作用 - 我得到:
"NasHelper::Production.lan(bar)"
我怎样才能减少这种情况,或者我必须坚持使用我所拥有的东西?
答案 0 :(得分:1)
如果您担心的是最终使用String而不是对象,则可以使用String.constantize
(仅限Rails,使用标准Ruby,您必须实现此功能;它使用Object.const_get(字符串))
另一个选项是.const_get
(例如Object.const_get(x)
,其中x是你的字符串),它本身并没有正确嵌套,所以你必须拆分为“::”等等。
此外,还可以选择使用eval
来评估字符串。
但请注意:eval
应该非常谨慎地使用(它很强大),或者根本不使用。
修改:
这意味着代替:
@settings = "SomeHelper::#{@foo.development_mode}.lan(bar)"
你可以跑:
@settings = "SomeHelper::#{@foo.development_mode}".constantize.lan(bar)
有用的来源:
http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-constantize
http://www.ruby-forum.com/topic/183112
http://blog.grayproductions.net/articles/eval_isnt_quite_pure_evil
答案 1 :(得分:0)
在第一种情况下,@settings
会收到方法SomeHelper::Production.lan(bar)
的结果;在第二个中,@settings
只获取一个字符串。您可以使用send
method of Object
linked here来触发该方法,或eval
,但这不是我的首选。
看起来你可能正在重新发明一个轮子--Rails已经将“环境”的概念很好地连接到了所有东西 - 它们在app/config/environments
中定义。您在启动服务器时设置环境,并且可以像Rails.env.production?
那样进行测试。要创建新环境,只需复制最接近新环境的现有环境文件,例如,将production.rb
复制到beta.rb
并根据需要进行修改,然后测试Rails.env.beta?
。
但这仍然让你测试到处都是哪一个。您可以添加config
哈希值(例如config.some_helper.lan = 'bar'
),您可以直接将该值分配给@settings
。您必须确保在所有环境中都有默认值或定义,但我认为这可能是正确的方法......不知道您的目标是什么。