使用初始的Rails项目,并使用
Rubocop分析代码风格.这让我完全怀疑Ruby的嵌套类在Rails的上下文中是如何工作的.例如,在我的引擎中,我有一个模型:
# app/models/app_core/tenant.rb module AppCore class Tenant < ActiveRecord::Base end end
和控制器:
# app/controllers/app_core/tenant/members_controller.rb module AppCore class Tenant::MembersController < ApplicationController end end
在模型的情况下,模块与路径相同,类名与文件名相同.在控制器的情况下,路径的第二部分“租户”是类名称的一部分.
Rubocop告诉我,在Tenant :: MembersController行中,我应该“使用嵌套类定义而不是紧凑样式”,所以如果我正确理解…
module AppCore class Tenant class MembersController < ApplicationController end end end
…这不应该有所作为.
现在,我的问题是我有AppCore :: Tenant作为一个模型,但AppCore :: Tenant看起来被重新打开,并且MembersController类被添加到它作为一个嵌套类.这是否意味着我的租客类总是会有这样的嵌套类?我需要将我的模型和控制器路线命名为不同的东西吗?这是完全没有什么可担心的吗?不清楚这是什么意思.
解决方法
一个微妙的区别是你的范围是不同的,这可能会导致错误.在第一种情况下,常量将在AppCore中查找,而在第二种情况下,常量将在AppCore :: Tenant中查找.如果您完全限定常数名称,那么这并没有什么意义.
Foo = :problem module A Foo = 42 # looks up A::Foo because of lexical scope module B def self.foo Foo end end end # looks up ::Foo because of lexical scope module A::C def self.foo Foo end end # Looks up A::Foo,fully qualified ... ok technically ::A::Foo is fully qualified,but meh. module A::D def self.foo A::Foo end end A::B.foo # => 42 A::C.foo # => :problem A::D.foo # => 42
如果您是在AppCore :: Tenant中定义的常量来自MembersController,那么它可能会对您有所作为.微妙但可能重要,并且很好的意识到.当我有一个具有String子模块的Util模块时,我在现实生活中打了这个.我把一个方法移动到Util,它破坏了,因为该方法中的String现在引用了Util :: String.之后我修改了一些命名约定.
您的租户模块将始终将MembersController作为嵌套类.您的代码库中的其他任何地方可以参考AppCore :: Tenant :: MembersController.如果你想要更好的分离,那么你应该以不同的方式来命名你的模型类,或者把它们放在一个模块中,比如AppCore :: Model或者类似的.如果您使用Rails,则必须降低某些约定,但是所需的配置并不是太差.