Rails 3.2:从可安装引擎添加种子任务

时间:2012-08-28 14:20:51

标签: ruby-on-rails ruby-on-rails-3 rubygems rake

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

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

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

所以我要问的是基本上如何让rake db:seed任务在我的gemified引擎中定义,只需要在gemfile中使用gem?

2 个答案:

答案 0 :(得分: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定义为perquisite的任何内容。

答案 1 :(得分:1)

请尝试扩展Rails::Generators::Base

This is the mechanism as given in the docs

  

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

所以

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运行的应用目录