在模块中嵌套类与使用模块作为类名

时间:2016-06-13 17:25:53

标签: ruby module namespaces

module and class with the same name in Rails project类似,但我试图理解为什么把它全部放在一行上但是使用单独的行却没有。

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

我有app/models/user/as_invitation.rb。如果它看起来如下,它工作正常:

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

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

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

我怀疑Ruby对模块/类使用相同的命名空间,并且因为我已经有User类(模型),所以它与User模块(模块与模型)冲突。 / p>

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

我试图理解Ruby / Rails如何实现这一点以及确定我是否继续使用::User::AsInvitation在一条线上,无论我是否会发现自己一条没有划桨的河流。

2 个答案:

答案 0 :(得分:0)

@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::AsActive vs User)。模块和类使用相同的常量命名空间(可能不是最好的词来描述它,但它对我来说很有意义)。

答案 1 :(得分:0)

至少在 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