简体   繁体   English

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

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

Similar to module and class with the same name in Rails project , but I'm trying to understand why putting it all on one line works but using separate lines does not.类似于Rails 项目中具有相同名称的模块和类,但我试图理解为什么将它们全部放在一行中有效,但使用单独的行却行不通。

Working with inviting new users to an account.使用邀请新用户加入帐户。 My user model has the minimum validation, and I use subclasses with additional behavior.我的user模型具有最少的验证,并且我使用具有附加行为的子类。 This is similar to service objects, but subclasses are cleaner than services most of the time because they are all kept in the /app/models folder and is easier to maintain.这类似于服务对象,但大多数时候子类比服务更干净,因为它们都保存在/app/models文件夹中,更易于维护。

I have app/models/user/as_invitation.rb .我有app/models/user/as_invitation.rb When it looks like the following, it works fine:当它看起来像以下时,它工作正常:

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

But when I have this, it does not work: "User is not a module".但是当我有这个时,它不起作用:“用户不是模块”。

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

My suspicion is that Ruby uses the same namespace for modules/classes, and since I already have a User class (model), it collides with the User module (module vs model).我怀疑 Ruby 对模块/类使用相同的命名空间,并且由于我已经有一个User类(模型),它与User模块(模块与模型)发生冲突。

I can use the ::User::AsInvitation format and it works, but it bugs me when magic happens.我可以使用::User::AsInvitation格式并且它有效,但是当魔术发生时它让我::User::AsInvitation As another solution, I can use the module name Users plural, but it makes more sense to me to use singular User as the namespace.作为另一种解决方案,我可以使用模块名称Users复数,但对我来说使用单数User作为命名空间更有意义。

I'm trying to understand a bit under-the-hood of how Ruby/Rails implement this as well as determine if I go ahead and use ::User::AsInvitation on one line, whether I am going to find myself down a river without a paddle.我试图了解 Ruby/Rails 如何实现这一点,并确定我是否继续并在一行中使用::User::AsInvitation ,我是否会发现自己::User::AsInvitation没有桨。

@JörgWMittag answered my question in the comments (if you want to throw this into an answer I'll accept it): @JörgWMittag 在评论中回答了我的问题(如果你想把它放到答案中,我会接受):

module User
end

and

class User < ActiveRecord::Base
end

both resolve to the same constant in Ruby ( User ) and thus collide, whereas:两者都解析为 Ruby ( User ) 中的相同常量并因此发生冲突,而:

module User
  class AsActive < ActiveRecord::Base
  end
end

and

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

resolves to different Ruby constant ( User::AsActive vs User ).解析为不同的 Ruby 常量( User::AsActiveUser )。 Modules and classes use the same constant namespace (may not be best word to describe it, but it makes sense to me).模块和类使用相同的常量命名空间(可能不是描述它的最佳词,但对我来说很有意义)。

The correct way, at least in Rails 6, to do this in separate files is:至少在 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