6

rake db:seed作業を開始するために、DB の基本の一部を入力しすぎることを使用する Rails アプリケーションがあります。これは、小さなインフラストラクチャと、YAML を DB にロードするために誰かが作成した Fixtures.rb を介して機能します。
私がやろうとしているのは、このインフラストラクチャを自分の宝石に移動して、他の場所で再び使用できるようにすることです。これには、自分の宝石のモデルのいくつかを宝石のシードタスク (私が望むもの) を介して挿入する必要があります。メインアプリでの呼び出しdb:seedまたは同様のものから実行されていること)、メインアプリが独自のシードを使用してgemのモデルの一部をプッシュすること。これの 2 番目の部分は、私が既に作業を行っています。これは、与えられた Fixtures.rb ファイルの簡単な修正でした。今やりたいこと:

  • Fixtures.rb を gem に移動します。gem でこれを実行するソースはまだありません。これを行うには、おそらく からファイルを要求し、[MyGem::Engine.root, 'lib', ...].joinYAML ファイルを DB にロードするためのパスを指定してメソッドを呼び出すことができますが、これが機能しない理由はわかりません。
  • rake db:seedの宝石で定義されたタスクを実行します。gem (エンジン) の lib/tasks の下に .rake ファイルを追加しましたが、メイン アプリの rakefile から呼び出すことができないようです。
    明確にするために、私がやりたいことは、gem (メインアプリではなく、またはメインアプリの1行のコード) を使用して、メインアプリのシードタスクに依存関係を追加し、誰かがrake db:seedメインアプリで実行されたときにgem は、メインのアプリ開発者がそれらについて知る必要なく、追加のシードを実行します。

私が避けたい汚い解決策は、メイン アプリ内の gem から .rake ファイルをロードするか、メイン アプリ内の gem から .rake ファイルを gem にロードすることです。

だから私が求めているのは、基本的rake db:seedに、gemfileに必要なgemを持つだけで、gem化されたエンジン内で定義されたタスクをタスクに実行させる方法ですか?

4

2 に答える 2

3

これを尋ねた直後に、私はそれを理解しました。ここから最初のステップが取られました:メインアプリにgemsタスクを追加する方法

次に、タスクファイル内

#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 に答える