如何在 Rails 7 Minitest 中设置命名空间模型夹具?

How to set up namespaced model fixtures in Rails 7 Minitest?

提问人:Backo 提问时间:3/21/2023 最后编辑:Backo 更新时间:3/23/2023 访问量:305

问:

我有一个类似的问题,就像这个旧问题一样,与在 Rails 7 中使用命名空间模型固定装置进行has_one belongs_to关联有关。

关于ActiveRecord,在我的模型文件中,我有:

# app/models/user.rb
class User < ApplicationRecord
  has_one :setting, :class_name  => 'Users::Setting', :foreign_key => 'user_id'
end

# app/models/users/setting.rb
class Users::Setting < ApplicationRecord
  belongs_to :user, :class_name  => 'User', :foreign_key => 'user_id'
end

# app/models/users.rb
module Users
  def self.table_name_prefix
    'users_'
  end
end

关于夹具,在 test/fixtures/users.yml 文件中,我已创建并成功将以下内容用于用户模型:

# test/fixtures/users.yml

foo:
  id: 1
  name: Foo
  email: [email protected]
  ...

bar:
  id: 2
  name: Bar
  email: [email protected]
  ...

但是,我在为 Users::Setting 模型设置夹具时遇到了麻烦。我尝试创建test/fixtures/users/settings.yml文件并使用以下文件但没有成功:

# test/fixtures/users/settings.yml

_fixture:
  model_class: Users::Setting

foo_setting:
  id: 1
  user_id: 1
  ...

# foo_setting:
#   id: 1
#   user: foo
#   ...

运行测试时,出现如下错误:

Minitest::UnexpectedError:ActiveRecord::Fixture::FixtureError:表 “users”没有名为“user_id”/“user”的列。

在用户夹具中,我还尝试使用以下内容,但遇到了相同的 Minitest 错误:

# test/fixtures/users.yml

foo:
  id: 1
  name: Foo
  email: [email protected]
  setting: foo_setting (Users:Setting) # <<<
  ...

我也尝试像这样编辑test/test_helper.rb文件,但我得到了同样的Minitest错误:

class ActiveSupport::TestCase
  fixtures :all
  set_fixture_class 'users/settings' => Users::Setting
end

在 test/integration/user_flows_test.rb 中,我有:

# test/integration/user_flows_test.rb

require "test_helper"

class UserFlowsTest < ActionDispatch::IntegrationTest
  fixtures :users

  test "can something" do
    user = users(:foo)
    ...
  end
end

如何声明命名空间 Users::Setting 的工作夹具?

ruby-on-rails testing 命名空间 fixtures minitest

评论

1赞 max 3/21/2023
在定义嵌套常量时,应使用显式嵌套。使用范围解析运算符会导致各种奇怪和令人不安的持续查找和行为,因为它没有设置正确的模块嵌套。github.com/rubocop/ruby-style-guide#namespace-definitionmodule Users; class Setting ...::
1赞 max 3/21/2023
或者,当您使用 Zeitwerk 时,您可以省略外部模块,它会根据 to 文件夹结构隐式嵌套它。例如,如果你有,它将自动创建和模块,你会得到.不过,显式嵌套通常是可取的。class Baz; endapp/foo/bar/baz.rbFooBarFoo::Bar::Baz
1赞 Backo 3/21/2023
@max 我尝试在 app/models/users/setting.rb 中进行显式嵌套(我更新了问题),但固定装置仍然不起作用。
1赞 max 3/22/2023
不过,这将使您免于将来许多潜在的头痛。
0赞 Backo 3/22/2023
我可以想象,但直到现在我从未遇到过命名间距的问题。

答:

1赞 Backo 3/23/2023 #1

找到解决方案:

  1. 在 test/test_helper.rb 中,我添加了set_fixture_class :users_settings => Users::Setting

测试/test_helper.rb

class ActiveSupport::TestCase
  ...

  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  # Namespaced models/fixtures
  set_fixture_class :users_settings => Users::Setting

  ...
end
  1. (回复)将包含 fixture 语句的文件命名为 users_settings.yml
  2. 已找到文件users_settings.yml at test/fixtures/users_settings.yml