gpt4 book ai didi

ruby-on-rails - `app` 目录中的命名空间

转载 作者:数据小太阳 更新时间:2023-10-29 07:38:54 24 4
gpt4 key购买 nike

在我们的 app 目录中,我们希望一些子目录包含命名空间类,一些子目录包含顶级类。例如:

  • app/models/user.rb 定义 ::User
  • app/operations/foo.rb 定义了 ::Operations::Foo
  • app/operations/user/foo.rb 定义 ::Operations::User::Foo

我们的 application.rb 包含以下配置:

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

这在大多数情况下工作正常,但有时在开发模式下和 Rails 的自动重新加载打开时,这会导致加载错误的类。例如,::User 被误认为是 Operations::User,反之亦然。

有没有办法配置此行为,使其正常工作?

如果没有,我能想到的唯一解决方法是为“命名空间”类创建第二个目录,按照 appapp_namespaced 的行。或者 app/namespaced,因为应用级代码应该位于 app 中。但这些对我来说似乎是丑陋的解决方法。

编辑:@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's fine and works.
::User.new
end
end
end

最佳答案

是的,这是 Rails 自动加载的缺点。默认情况下,它从 /app 加载所有内容,但第一级目录结构不是名称的一部分。这样 app/models/user.rb 就可以定义 User,而不是要求它是 Models::User

您不需要弄乱加载路径。此处提供了几种方法/解决方法。

  1. 在我当前的项目中,我们只是将命名空间目录加倍。这意味着如果我们要定义 ServiceObjects::User::Import,我们将其放入 app/service_objects/service_objects/user/import.rb

    <
  2. 我个人更喜欢这种方法的变体,即将所有“非标准”内容放入 app/lib(可以是 app/custom或任何你想要的)。这样,就不会出现奇怪的目录名称重复,并且所有自定义代码都很好地包含在内。

关于ruby-on-rails - `app` 目录中的命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41485721/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com