Rails 自定义中间件在 GH CI 中未被识别

问题描述 投票:0回答:1

我第一次使用自定义中间件来标准化错误处理。我在

app/middleware/error_handler.rb
中定义了中间件并在我的主应用程序中使用。rb

...
require_relative "../app/middleware/error_handler"

module AppName
  class Application < Rails::Application
    ...
    config.middleware.use Middleware::ErrorHandler
    ...
  end
end

当路由到本地主机时,这在测试和开发中都运行良好。但是当我推送到 github 并且操作接管时,我在执行迁移后得到了这个

An error occurred while loading spec_helper.
Failure/Error: require_relative "../config/environment"

NameError:
  uninitialized constant ErrorHandler
# ./config/environment.rb:5:in `<top (required)>'
# ./spec/rails_helper.rb:6:in `require_relative'
# ./spec/rails_helper.rb:6:in `<top (required)>'
# ./spec/spec_helper.rb:3:in `<top (required)>'
No examples found.

这是我的行动/工作流程

name: Run RSpec

on:
  push:
    branches:
      - "*" # Trigger on push to any branch

jobs:
  test:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:16.1
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: ${{ secrets.ROUTE_RATER_DATABASE_PASSWORD }}
          POSTGRES_DB: postgres
        ports:
          - 5432:5432
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

      redis:
        image: redis
        ports:
          - 6379:6379
        options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: "3.3.0"

      - name: Install dependencies
        run: |
          gem install bundler
          bundle install --jobs 4 --retry 3

      - name: Setup DB, Run tests
        env:
          PGHOST: localhost
          PGUSER: postgres
          PGPORT: ${{ job.services.postgres.ports[5432] }}
          PGPASSWORD: ${{ secrets.DATABASE_PASSWORD }}
          REDIS_URL: redis://localhost:6379/1
          GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
          RAILS_ENV: test
        run: |
          bin/rails db:create db:migrate db:schema:load
          bundle exec rspec

ruby-on-rails github-actions middleware
1个回答
0
投票

app/middleware/error_handler.rb
预计会定义
ErrorHandler
,但您正在定义命名空间
Middleware::ErrorHandler

通常,如果您要请求

ErrorHandler
,它将从任何
根目录
中找到的第一个 error_handler.rb 文件加载,在本例中为
app/middleware/
。文件结构必须对应于相对于根目录的模块/类名称:

# app/middleware/error_handler.rb
#                ^^^^^^^^^^^^^
#                      |
class ErrorHandler # >-'
end

Rails 自动将

app/
下的目录配置为根目录。这样你就可以加载
ErrorHandler
而不需要它:

>> ErrorHandler
=> ErrorHandler

如果你要命名它:

# app/middleware/error_handler.rb

module Middleware
  class ErrorHandler
  end
end

您收到错误:

>> ErrorHandler
(irb):1:in `<main>': uninitialized constant ErrorHandler (NameError)

ErrorHandler
^^^^^^^^^^^^

这正是

zeitwerk
通过在生产环境或 ci 测试环境中急切加载应用程序所做的事情:

# config/environments/test.rb

config.eager_load = ENV["CI"].present?

在开发中,您可以仔细检查您的应用程序是否可以立即加载:

$ bin/rails zeitwerk:check

Hold on, I am eager loading the application.
expected file app/middleware/error_handler.rb to define constant ErrorHandler, but didn't

由于无论如何你都无法在启动过程中自动加载,所以你必须

require
并使用
Middleware::ErrorHandler
,只是不要将其放在autoload路径中。

您还可以使用

autoload_once_paths
autoload_lib_once
但您必须将
config.middleware.use
移至初始值设定项中:

# config/application.rb

config.autoload_lib_once(ignore: %w(assets tasks))
# config/initializers/middleware.rb

Rails.application.config.middleware.use Middleware::ErrorHandler
# lib/middleware/error_handler.rb

module Middleware
  class ErrorHandler
    # ...
  end
end
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.