如何进一步干燥此Rails控制器操作

时间:2012-11-15 20:48:31

标签: ruby-on-rails-3 dry

我们的应用程序使用了许多环境,因此我们可以在不破坏事物的情况下试验设置。在典型的控制器操作中,我有类似的东西:

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)"

我怎样才能减少这种情况,或者我必须坚持使用我所拥有的东西?

2 个答案:

答案 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。您必须确保在所有环境中都有默认值或定义,但我认为这可能是正确的方法......不知道您的目标是什么。