在 Rails 中包含模型时保留控制器的命名空间

Keep namespacing of a controller when including a model in Rails

我试图在包含模块时保留 class 的名称空间。 假设我有这些模型:

class Shop < ApplicationRecord
  self.abstract_class = true
end
class A::Shop < ::Shop
end
class B::Shop < ::Shop
end

这个控制器:

module A
  class ShopController < AuthenticatedController
    include Basic::Features
    def test
      p Shop.new #YES! its a A::Shop 
    end
  end
end

而这个模块:

module Basic
  module Features
    def test
      p Shop.new  #Shop (abstract)
    end
  end
end

在上面的例子中,命名空间在包含模块时被覆盖。 因为我想在我的代码库的多个地方使用 Basic::Features 模块,所以我想在将它包含在控制器中时自动在 A::ShopB::Shop 之间切换。

任何人都知道这是否可行,以及如何实现。

这是一种选择:

module Basic
  module Features
    def test
      p Object.const_get('::' + self.class.to_s.split('::').first + '::Shop')
    end
  end
end

如果你有更深的命名空间,它将不起作用,例如A::B::Shop,但它可以工作。同样在 rails 中,您可以使用 deconstantize 而不是 split

我认为您的代码不起作用的原因是因为它正在查找 A::ShopController 命名空间并且由于未找到它然后尝试根命名空间 :: 并找到 Shop .