如何在运行时在ruby中设置命名空间?

时间:2012-09-01 20:03:23

标签: ruby activerecord module namespaces metaprogramming

我有一个基于ActiveRecord的应用程序,可以通过命令行实用程序使用。在这样的应用程序中使模型命名空间有利于保持Object名称空间清洁。

我开始围绕这些ActiveRecord模型构建一个rails应用程序,虽然我已经克服了在命名空间中使用模型的一些初期麻烦,但我发现事情比我想要的更冗长。

我想要的是在命令行实用程序中使用时为programmaticaly设置我的ActiveRecord类的命名空间,并在Rails应用程序中使用时不为这些模型设置命名空间。

我知道文件本身可以在运行之前在需要之前进行更改,但我正在寻找Ruby语言本身的一些东西来干净利落地完成它。

1 个答案:

答案 0 :(得分:2)

如果没有看到一些代码,很难提供很好的建议,但这里有两种可能性。

  1. 听起来这个代码有两个客户端。也许让它成为一个引擎(只是一个奇特的宝石),你可以添加你的路径到自动加载路径,然后从宝石中使用它,而不会阻碍所有的垃圾废话。

  2. 也许创建一个常量然后在模型中重新打开它:

  3. 在某些初始值设定项中

    ActualNamespace = Class.new
    DynamicNamespace = ActualNamespace
    
    模型文件中的

    class DynamicNamespace
      class MyModel
      end
    end
    
    DynamicNamespace::MyModel # => ActualNamespace::MyModel
    

    然后是您的命令行应用

    DynamicNamespace = Object
    

    与没有名称空间相同:

    DynamicNamespace::MyModel # => MyModel
    

    现在你可能会遇到一些Rails魔法的困难,这很大程度上是基于反射。我不完全知道你会面对什么,但我希望表单在提交数据时开始生成错误的密钥。你可以通过定义DynamicNamespace.name或类似的东西来解决这个问题。

    自动加载,可能也会成为一个问题,但我认为你可以以某种方式声明自动加载路径(我不确定,但google搜索“rails autoloading”给出了一些有希望的结果,看起来它只是挂钩到Ruby的自动加载 - 尽管我认为这在Ruby 2.0中已经消失了)最糟糕的情况,你可以定义一个铁路来急切地为你加载dirs。这有点超出了我的联盟,但我认为你需要在应用程序初始化之前定义的铁路,所以你可能需要在config / application.rb中要求铁路

    不幸的是,在一天结束时,当你开始偏离Rails惯例时,生活开始变得艰难,你从未想过的所有魔法都会崩溃,所以你突然不得不潜入Rails代码库它正在做什么。