Ruby on rails Rails 3.2:从可装载引擎添加种子任务
我有一个rails应用程序,它使用了Ruby on rails Rails 3.2:从可装载引擎添加种子任务,ruby-on-rails,ruby-on-rails-3,rubygems,rake,Ruby On Rails,Ruby On Rails 3,Rubygems,Rake,我有一个rails应用程序,它使用了rakedb:seed来填充数据库中的一些基础知识以开始工作。这是通过一个小的基础设施和一个fixture来实现的。rb其他人编写了将YAML加载到DB中的命令。 我想做的是将这个基础设施转移到我自己的gem中,这样我就可以在其他地方再次使用它,这需要我通过gem的seed任务插入我自己的gem模型(我想通过调用db:seed或主应用程序中的类似任务来运行)主应用程序使用自己的种子推送一些gem的模型。第二部分我已经开始工作了,它是fixtures.rb文件中
rakedb:seed
来填充数据库中的一些基础知识以开始工作。这是通过一个小的基础设施和一个fixture来实现的。rb其他人编写了将YAML加载到DB中的命令。我想做的是将这个基础设施转移到我自己的gem中,这样我就可以在其他地方再次使用它,这需要我通过gem的seed任务插入我自己的gem模型(我想通过调用
db:seed
或主应用程序中的类似任务来运行)主应用程序使用自己的种子推送一些gem的模型。第二部分我已经开始工作了,它是fixtures.rb文件中的一个简单修复。
我现在想做的事情是:
- 将fixtures.rb移到gem中:我仍然没有任何源代码在gem中运行这个。现在要做到这一点,我可能需要
然后在那里调用一个方法,该方法具有将YAML文件从加载到DB的路径,我不明白为什么它不应该工作[MyGem::Engine.root,'lib',…]中的文件。join
- 获取
以运行在我的gem中定义的任务。我在gem(它是一个引擎)的lib/tasks下添加了.rake文件,但我似乎无法从主应用程序rakefile调用它们。rake db:seed
为了让自己明白,我想做的是通过gem(不是主应用程序-或者主应用程序中有一行代码)在主应用程序种子任务上添加一个依赖项,这样当有人在主应用程序中运行
时,gem将运行额外的种子,而主应用程序开发人员甚至不必知道它们rake db:seed
因此,我要问的基本上是如何让rake db:seed任务只需在gemfile中包含所需的gem,就可以在gemfile中执行gem中定义的任务?因此,在问了这个问题后,我很快就明白了。 第一步从这里开始: 然后在任务文件中
#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时,它运行我的seed任务定义为额外条件的任何东西。尝试扩展
Rails::Generators::Base
:
“生成器中的每个公共方法都是在调用生成器时执行的”
所以
classdbgenerator
这种方法将允许所有基于gem的seed数据复制到app dir中,以便运行
db:seed
run由于依赖于Rakefile
添加,因此很脆弱。Rails在Rails::generator中内置了一个反射器。为什么说它很脆弱?如果忘记将其添加到rakefile中,那么gem资产将被错误地放置。扩展的Rails::Generators::Base
确保这些资产将被包括在内。如果您想要一个条件包含,那么这应该是包含gem本身的条件。我的第一个想法是,对于一个有一些你可能不想包括在内的资产的创业板来说,这是1。创业板中的资产太多,或2。资产创业板是错误的机制。关键是我使用的是增强。这样,就没有人将它添加到rakefile中,而是将gem安装到rails应用程序中会自动使我的rake任务成为db:seed
的附加任务,无论如何都需要运行它。为了与gem合作,必须这样做。生成器也必须通过主机应用程序运行,然后db:seed也必须运行,不是吗?我必须考虑一下:Rails生成器组件和Rake take目标之间的责任差异。在以应用程序为中心的思维中,应用程序无法意识到额外的资产,即使它意识到了gem。
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