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.
Working with inviting new users to an account. My user
model has the minimum validation, and I use subclasses with additional behavior. 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.
I have 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).
I can use the ::User::AsInvitation
format and it works, but it bugs me when magic happens. 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.
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.
@JörgWMittag answered my question in the comments (if you want to throw this into an answer I'll accept it):
module User
end
and
class User < ActiveRecord::Base
end
both resolve to the same constant in Ruby ( User
) and thus collide, whereas:
module User
class AsActive < ActiveRecord::Base
end
end
and
class ::User::AsActive < ActiveRecord::Base
end
resolves to different Ruby constant ( User::AsActive
vs 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:
# 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.