Distributing names in the `app` directory

In our catalog, appwe want some subdirectories to contain classes with names, and some to top-level classes. For instance:

  • app/models/user.rb defines ::User
  • app/operations/foo.rb defines ::Operations::Foo
  • app/operations/user/foo.rb defines ::Operations::User::Foo

Our application.rbcontains the following configuration:

config.paths = Rails::Paths::Root.new(Rails.root)
config.paths.add 'app/models', eager_load: true
config.paths.add 'app', eager_load: true

This works fine in most cases, but sometimes in development mode and when Rails startup is turned on, this leads to loading of the wrong classes. For example, it is ::Usermistaken for Operations::Userand vice versa.

Is there a way to configure this behavior so that it works without errors?

If not, the only workaround I can think of is to create a second directory for the classes with names along the appand lines app_namespaced. Or else app/namespaced, since application-level code must be inside app. But they seem like ugly workarounds to me.

Edit: small example given by @dgilperez:

# app/models/user.rb
class User
end

# app/models/group.rb
class Group
  def some_method
    # Since we're in a top-level namespace, User should always
    # resolve to ::User. But, depending on some seemingly random
    # factors, it sometimes resolves to Operations::User.
    User.new
  end
end

# app/operations.rb
module Operations
end

# app/operations/user/create.rb
module Operations::User
  class Create
    def some_method
      # Here, as expected, I need to prefix with "::" as
      # 'User' would refer to the module we're currently in.
      # That fine and works.
      ::User.new
    end
  end
end
+4
source share
1 answer

Yes, this is a drawback of auto loading rails. By default, it loads everything from /app, but the first level of the directory structure is not part of the names. This is so that it app/models/user.rbcan determine User, does not require it to be Models::User.

. / .

  • namespacing. , ServiceObjects::User::Import, app/service_objects/service_objects/user/import.rb

  • , "" app/lib ( app/custom ). , , .

0

Source: https://habr.com/ru/post/1665874/


All Articles