[英]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::AsActive
与User
)。 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.