填充常量值表

发布于 2024-07-14 03:28:42 字数 410 浏览 2 评论 0原文

在 Rails 应用程序中,我需要数据库中的一个表来包含常量数据。

该表内容暂时不打算更改,但我不想将内容放入代码中,以便能够在需要时更改它。

我尝试在创建它的迁移中填充该表,但这似乎不适用于测试环境并破坏了我的单元测试。 在测试环境中,我的模型永远无法返回任何值,而在我的开发环境中则可以。

即使在测试环境中,有没有办法正确填充该数据库? 是否有另一种方法来处理这些不应该在代码中的数据?

编辑

感谢大家的回答,特别是 Vlad R 解释问题。

我现在明白为什么我的数据没有在测试中加载。 这是因为测试环境使用 db:load rake 命令直接加载架构而不是运行迁移。 仅将我的值放入迁移中而不是放入架构中,因此不会加载这些值进行测试。

In a Rails application, I need a table in my database to contain constant data.

This table content is not intended to change for the moment but I do not want to put the content in the code, to be able to change it whenever needed.

I tried filling this table in the migration that created it, but this does not seem to work with the test environment and breaks my unit tests. In test environment, my model is never able to return any value while it is ok in my development environment.

Is there a way to fill that database correctly even in test environment ? Is there another way of handling these kind of data that should not be in code ?

edit

Thanks all for your answers and especially Vlad R for explaining the problem.

I now understand why my data are not loaded in test. This is because the test environment uses the db:load rake command which directly loads the schema instead of running the migrations. Having put my values in the migration only and not in the schema, these values are not loaded for test.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

软糖 2024-07-21 03:28:42

您可能观察到的是,测试框架没有运行迁移 (db:migrate),而是直接加载 db/schema.rb (db:load)。

您有两个选择:

  1. 继续使用迁移进行生产和开发; 对于测试环境,将常量数据添加到 db/fixtures 中相应的 yml 文件中,
  2. 保持现有 db/fixtures 文件不变,并以与 db/fixtures 相同的方式创建另一组 yml 文件(包含常量数据),但是在进行 rake db:load 模式初始化时,测试和生产/开发环境都可以使用

覆盖那些使用 db:load (而不是 db:migrate)的场景 - 例如测试,使用更快的速度在新的开发机器上启动新数据库db:load 而不是 db:migrate 等)是在 RAILS_APP/lib/tasks 中创建一个嵌入式 rakefile,通过从“种子”yml 文件(每个模型一个)加载常量初始化数据来增强 db:load 任务进入数据库。

使用 db:seed rake 任务作为示例。 将种子数据放入 db/seeds/.yml 中

#the command is: rake:db:load
namespace :db do
  desc 'Initialize data from YAML.'
  task :load => :environment do
    require 'active_record/fixtures'
    Dir.glob(RAILS_ROOT + '/db/seeds/*.yml').each do |file|
      Fixtures.create_fixtures('db/seeds', File.basename(file, '.*'))
    end
  end
end

要涵盖增量场景 (db:migrate),请定义一个与上面定义的任务执行相同操作的迁移。

如果您的种子数据发生变化,您将需要添加另一次迁移来删除旧的种子数据并加载新的数据,这在外键依赖等情况下可能并不简单。

What you are probably observing is that the test framework is not running the migrations (db:migrate), but loading db/schema.rb directly (db:load) instead.

You have two options:

  1. continue to use the migration for production and development; for the test environment, add your constant data to the corresponding yml files in db/fixtures
  2. leave the existing db/fixtures files untouched, and create another set of yml files (containing the constant data) in the same vein as db/fixtures, but usable by both test and production/development environments when doing a rake db:load schema initialization

To cover those scenarios that use db:load (instead of db:migrate - e.g. test, bringing up a new database on a new development machine using the faster db:load instead of db:migrate, etc.) is create a drop-in rakefile in RAILS_APP/lib/tasks to augment the db:load task by loading your constant intialization data from "seed" yml files (one for each model) into the database.

Use the db:seed rake task as an example. Put your seed data in db/seeds/.yml

#the command is: rake:db:load
namespace :db do
  desc 'Initialize data from YAML.'
  task :load => :environment do
    require 'active_record/fixtures'
    Dir.glob(RAILS_ROOT + '/db/seeds/*.yml').each do |file|
      Fixtures.create_fixtures('db/seeds', File.basename(file, '.*'))
    end
  end
end

To cover the incremental scenarios (db:migrate), define one migration that does the same thing as the task defined above.

If your seed data ever changes, you will need to add another migration to remove the old seed data and load the new one instead, which may be non-trivial in case of foreign-key dependencies etc.

挖鼻大婶 2024-07-21 03:28:42

请查看我关于加载种子数据的文章。

有多种方法可以做到这一点。 我喜欢一个名为 db:populate 的 rake 任务,它可以让您指定固定数据正常的 ActiveRecord 创建语句。 为了将数据放入测试中,我只是在我的 test_helper 中加载此填充文件。 但是,我想我将切换到已经填充了种子数据的测试数据库。

还有一个名为 SeedFu 的插件,可以帮助这个问题。

无论您做什么,我建议不要为此使用固定装置,因为它们不会验证您的数据,因此很容易创建无效记录。

Take a look at my article on loading seed data.

There's a number of ways to do this. I like a rake task called db:populate which lets you specify your fixed data in normal ActiveRecord create statements. For getting the data into tests, I've just be loading this populate file in my test_helper. However, I think I am going to switch to a test database that already has the seed data populated.

There's also plugin called SeedFu that helps with this problem.

Whatever you do, I recommend against using fixtures for this, because they don't validate your data, so it's very easy to create invalid records.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文