繁体   English   中英

在模块中嵌套类与使用模块作为类名的一部分

[英]Nesting class in module vs using module as part of class name

类似于Rails 项目中具有相同名称的模块和类,但我试图理解为什么将它们全部放在一行中有效,但使用单独的行却行不通。

使用邀请新用户加入帐户。 我的user模型具有最少的验证,并且我使用具有附加行为的子类。 这类似于服务对象,但大多数时候子类比服务更干净,因为它们都保存在/app/models文件夹中,更易于维护。

我有app/models/user/as_invitation.rb 当它看起来像以下时,它工作正常:

class ::User::AsInvitation < ::User
  # ...
end

但是当我有这个时,它不起作用:“用户不是模块”。

module User
  class AsInvitation < ::User
    # ...
  end
end

我怀疑 Ruby 对模块/类使用相同的命名空间,并且由于我已经有一个User类(模型),它与User模块(模块与模型)发生冲突。

我可以使用::User::AsInvitation格式并且它有效,但是当魔术发生时它让我::User::AsInvitation 作为另一种解决方案,我可以使用模块名称Users复数,但对我来说使用单数User作为命名空间更有意义。

我试图了解 Ruby/Rails 如何实现这一点,并确定我是否继续并在一行中使用::User::AsInvitation ,我是否会发现自己::User::AsInvitation没有桨。

@JörgWMittag 在评论中回答了我的问题(如果你想把它放到答案中,我会接受):

module User
end

class User < ActiveRecord::Base
end

两者都解析为 Ruby ( User ) 中的相同常量并因此发生冲突,而:

module User
  class AsActive < ActiveRecord::Base
  end
end

class ::User::AsActive < ActiveRecord::Base
end

解析为不同的 Ruby 常量( User::AsActiveUser )。 模块和类使用相同的常量命名空间(可能不是描述它的最佳词,但对我来说很有意义)。

至少在 Rails 6 中,在单独的文件中执行此操作的正确方法是:

# models/user.rb
class User < ApplicationRecord
end

# models/user/as_invitation.rb
class User
   class AsInvitation < User
   # ...
   end
end

# config/routes.rb
resources :users
namespace :user do
  resources :as_invitations
end

# controllers/users_controller.rb
class UsersController < ApplictionController
end

# controllers/user/as_invitations_controller.rb
class User::AsInvitationsController < UsersController
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM