6

我有一个 Rails 应用程序,它使用rake db:seed了我的数据库中的一些基础知识来开始工作。这通过一个小基础设施和一个其他人编写的将 YAML 加载到数据库中的 fixtures.rb 来工作。
我想要做的是把这个基础设施移动到我自己的gem中,这样我就可以在其他地方再次使用它,这需要我都通过gem的种子任务插入一些我自己的gem模型(我想要从主应用程序中的调用db:seed或类似的东西运行)并且主应用程序使用它自己的种子推送一些 gem 的模型。我已经开始工作的第二部分,它是在我收到的 fixtures.rb 文件中的一个简单修复。我现在想做的事情:

  • 将 fixtures.rb 移动到 gem 中:我仍然没有任何源在 gem 中运行它。现在要做到这一点,我可能需要从那里调用文件,[MyGem::Engine.root, 'lib', ...].join然后在那里调用一个方法,该方法具有将 YAML 文件从加载到数据库中的路径,我不明白为什么它不应该工作。
  • rake db:seed开始运行我的 gem 中定义的任务。我已经在我的 gem(它是一个引擎)的 lib/tasks 下添加了 .rake 文件,但我似乎无法从主应用程序 rakefile 调用它们。
    为了让自己清楚,我想做的是通过 gem(不是主应用程序 - 或在主应用程序中使用 1 行代码)添加对主应用程序种子任务的依赖项,以便当有人rake db:seed在主应用程序中运行时gem 将运行额外的播种,而主应用程序开发人员甚至不必知道它们。

我想避免的肮脏解决方案是从主应用程序内的 gem 加载 .rake 文件,或者从主应用程序中的 gem 加载 seed.rb 文件。

所以我要问的基本上是如何通过rake db:seed在gemfile中拥有gem来使任务执行我的gemified引擎中定义的事情?

4

2 回答 2

3

所以在问这个问题后不久,我就明白了。第一步是从这里开始的:How to add a gems tasks to the main app

然后在任务文件中

#lib/task/some_task.rake
Rake::Task['db:seed'].enhance ['my_seed_task']

#lib/tasks/my_seed_task.rake
task 'my_seed_task' do
  ...
end

现在,当我在主应用程序中运行时rake db:seed,它会运行 my_seed_task 定义为附加项的任何内容。

于 2012-08-28T14:26:08.490 回答
1

而是尝试扩展Rails::Generators::Base.

这是文档中给出的机制

“调用生成器时执行生成器中的每个公共方法”

所以

class DbGenerator < Rails::Generators::Base
  source_root File.expand_path('../../../../db', __FILE__)

  def copy_seeds_file
    copy_file 'seeds.rb', 'db/seeds.rb'
  end

  def copy_seeds_dir
    Dir.foreach seeds_dir do |file|
      copy_file "seeds/#{file}", "db/seeds/#{file}"  unless file.match /^\./
    end
  end

  def seeds_dir
    File.expand_path 'seeds', self.class.source_root
  end
end

这种方法将允许所有基于 gem 的种子数据复制到应用程序目录中以供db:seed运行

于 2012-08-28T16:00:30.507 回答