相关疑难解决方法(0)

Rails 6:Zeitwerk::NameError 不从模块加载类

我有一个看起来像这样的文件

#app/services/account/authenticate/base.rb
module Account
  module Authenticate
    AuthenticateError = Class.new(StandardError)

    class Base < ::Account::Base
      def self.call(*attrs)
        raise NotImplementedError
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

现在当我运行代码时rails c出现错误

> ::Account::Authenticate::AuthenticateError
=> NameError (uninitialized constant Account::Authenticate::AuthenticateError)
> ::Account::Authenticate.constants
=> [:Base, :ViaToken]
Run Code Online (Sandbox Code Playgroud)

所以 rails 没有看到 AuthenticateError 类。但是当我从这个文件夹创建一个嵌套类时

=> Account::Authenticate::ViaToken
> ::Account::Authenticate.constants
=> [:Base, :AuthenticateError, :ViaToken]
Run Code Online (Sandbox Code Playgroud)

AuthenticateError 类现在可见

> ::Account::Authenticate::AuthenticateError
=> Account::Authenticate::AuthenticateError
Run Code Online (Sandbox Code Playgroud)

这个问题的解决方案是创建一个单独的文件authenticate_error.rb,它从一开始就可以工作,但这个解决方案对我来说并不理想。是否有任何解决方案可以预加载所有类或 smth?

(Ruby 2.6 和 Rails 6.0.0.rc2)

ruby ruby-on-rails

15
推荐指数
2
解决办法
8231
查看次数

如何忽略 Zeitwerk for Rails 6 中的文件夹?

简单的问题,但不知何故,答案让我望而却步。

在使用 Zeitwerk 迁移到 Rails 6 时,我得到:

Please, check the "Autoloading and Reloading Constants" guide for solutions.
 (called from <top (required)> at APP_ROOT/config/environment.rb:7)
rails aborted!
Zeitwerk::NameError: wrong constant name Enforce-calls-to-come-from-aws inferred by Module from directory

  APP_ROOT/app/junkyard/enforce-calls-to-come-from-aws

Possible ways to address this:

  * Tell Zeitwerk to ignore this particular directory.
  * Tell Zeitwerk to ignore one of its parent directories.
  * Rename the directory to comply with the naming conventions.
Run Code Online (Sandbox Code Playgroud)

这看起来很棒:这是一个垃圾文件夹,永远不应加载,因此忽略它是完全有道理的。

https://github.com/fxn/zeitwerk 上的 Zeitwerk 文档说

tests = "#{__dir__}/**/*_test.rb"
loader.ignore(tests)
loader.setup …
Run Code Online (Sandbox Code Playgroud)

ruby ruby-on-rails ruby-on-rails-6

11
推荐指数
2
解决办法
3733
查看次数

Rails 6 中的自动加载和 Zeitwerk 模式

在 Rails 6 的 Zeitwerk 模式中,这些代码中的任何一个都折旧了吗?

 class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2

    # config/application.rb
    config.i18n.load_path += Dir[Rails.root.join("config", "locales", "**", "*.{rb,yml}")]
    config.i18n.fallbacks = true

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
    config.autoload_paths += ["#{config.root}/app/queries/"]


    # https://gist.github.com/maxim/6503591 (should remove …
Run Code Online (Sandbox Code Playgroud)

ruby-on-rails ruby-on-rails-6

5
推荐指数
1
解决办法
2661
查看次数

Rails 6+、zeitwerk 自动加载器和命名空间常量

Rails 6+ 的默认自动加载器是 zeitwerk,这似乎比以前的方法有了很大的改进。

但是,zeitwork 遵循 Rails 项目的约定,即其中的任何内容app/*都是自动加载的,不需要命名空间。

这非常app/models/user.rb有用,因为您不必使用Models::User但可以只引用User.

但是,我添加了自己的app/services目录,并将我的服务对象命名为Services::Users::Create,它将映射到app/services/users/create.rb.

Zeitwork 正在抛出我的类常量不存在的错误,因为它是预期的Users::Create(没有Services::前缀)。

无论如何要配置 zeitwork 以Services::在这些实例中要求命名空间?在我看来,阅读代码Services::Users::Create并知道您正在查看app/services/users/create.rb文件要干净得多。

如果只有Users::Create,一般的 Rails 开发人员可能会查找该app/models/users/create.rb文件。

我不喜欢命名它的方法Users::CreateService,它对我来说似乎很不雅。

我不能是唯一一个使用这样的约定的人;有没有其他人遇到过解决方案?我仍在浏览所有 zeitwerk 文档以寻找解决方案,但还没有找到。

autoload ruby-on-rails-6 zeitwerk

4
推荐指数
1
解决办法
1521
查看次数