【问题标题】:Rails - call to engine_name seems to be ignoredRails - 对 engine_name 的调用似乎被忽略了
【发布时间】:2013-04-18 16:11:28
【问题描述】:

我想制作一个由两个命名空间隔离的引擎。也就是说,比如说我想制作一个引擎,它的类都在里面:

Car::BMW

因此,例如,我的模型应该放在:

app/models/car/bmw/

而且我的表格应该以例如为前缀:

car_bmw_

我试图通过在lib/car/bmw/engine.rb 中包含此代码来完成此操作

module Car
  module BMW
    class Engine < ::Rails::Engine
      isolate_namespace Car::BMW # This will call: engine_name 'car_bmw'
    end
  end
end

但是,每当我生成模型时,使用此代码,模型都会放置在:

app/models/car

并且表格的前缀是:

car_

我做错了什么?我使用的rails版本是4.0.0.beta1


编辑

我在Rails::Generators::NamedBase找到了这个方法

def namespaced_path
  @namespaced_path ||= namespace.name.split("::").map {|m| m.underscore }[0]
end

如您所见,它只占用命名空间的第一部分。有人知道为什么是这样吗?

这是 Rails 中的一个错误,还是我不应该让我的类具有双重命名空间?


这是我用来修复生成器的快速技巧。

require 'rails/generators'

Rails::Generators::NamedBase.class_eval do
  protected
    def namespaced_class_path
      @namespaced_class_path ||= [namespaced_path.split('/')] + @class_path
    end

    def namespaced_path
      @namespaced_path ||= namespace.name.split("::").map {|m| m.underscore }.join('/')
    end

    def class_name
      ([file_name]).map!{ |m| m.camelize }.join('::')
    end
end

【问题讨论】:

    标签: ruby-on-rails rails-engines ruby-on-rails-4


    【解决方案1】:

    使用这样的类

    module Car
      module BMW
        class Engine < ::Rails::Engine
          isolate_namespace Car::BMW # This will call: engine_name 'car_bmw'
          paths["app/models"] << "app/models/car/bmw"
        end
      end
    end
    

    将允许您从您指定的子目录加载模型。不过,我不能说这是否会影响生成过程。

    还有更多配置选项,请参见例如here。编辑它们以满足您的需求。

    【讨论】:

    • 谢谢,但加载模型已经“开箱即用”了。确实是生成过程没有按我认为的那样工作。
    【解决方案2】:

    我不明白你为什么想要那个。如果你想在你的Car 引擎之间共享功能,继承可能不是办法。如果你真的想要的话,你可能会拥有它的初始风格,即在汽车引擎中安装 BMW 引擎。

    如果 Car 不是您想要添加功能并在其他子模块之间共享的模块,则将其删除。

    如果您希望像 Car::BMW 这样的汽车引擎共享功能,那么您可以将其作为外部依赖项。您所有的汽车引擎都可能需要ActsAsACar gem 或其他东西。

    我仍然很难弄清楚为什么要使用双重命名空间。

    【讨论】:

    • 它主要不是关于共享功能,而是关于避免大型项目中的名称冲突。例如,如果您查看 Refinery 的源代码,您会发现他们的大多数模型也是双重命名空间的。
    • 所以这一切只是为了避免名字冲突?我创建了一个内部 CMS Rails 引擎,它也具有双重命名空间,无论是用于单表继承还是关注点 (active_support),但我不会为此使用命令行生成器。仅仅是为了搭建脚手架吗?
    • 是的,这确实是重点。我当然也可以为类名添加前缀,但如果名称空间可用,那对我来说看起来很傻。现在,我觉得有点奇怪,可以有一个双重命名空间的引擎,但是生成器不能正常工作。
    • rails g model Foo::Bar::Gong 对我来说效果很好。我得到 /app/models/foo/bar/gong.rb 甚至 /app/models/foo/bar。 rb 因为它不存在!但你是对的,他们采取了在类名前加前缀的方法。对我来说也是一样。那么又是什么问题呢?
    猜你喜欢
    • 2021-10-28
    • 2016-09-30
    • 2012-03-11
    • 1970-01-01
    • 1970-01-01
    • 2017-12-05
    • 2012-03-08
    • 2015-12-11
    • 2014-04-15
    相关资源
    最近更新 更多