Rails 3.2:从可挂载引擎添加种子任务



我有一个使用rake db:seed的rails应用程序,它也在我的DB中填充了一些基础知识以开始工作。这是通过一个小的基础设施和fixtures.rb实现的,其他人写了这个fixtures.rp来将YAML加载到DB中
我想做的是把这个基础设施移到我自己的gem中,这样我就可以在其他地方再次使用它,这需要我通过gem的种子任务插入我自己的一些gem模型(我想通过调用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(而不是主应用程序,或者在主应用程序中有一行代码)向主应用程序种子任务添加依赖项,这样当有人在主应用中运行rake db:seed时,gem将运行额外的种子,而主应用程序开发人员甚至不必知道它们

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

所以我要问的基本上是,如何让rake db:seed任务只需在gemfile中拥有所需的gem就可以在我的gemized引擎中完成定义的事情?

所以在问了这个问题后不久,我就明白了。第一步是从这里开始的:如何将宝石任务添加到主应用

然后在任务文件中

#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定义的任何额外功能。

尝试扩展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运行的应用程序目录

最新更新