web-dev-qa-db-ja.com

Railsの環境でRakeタスクに引数を渡す方法は?

次のように引数を渡すことができます。

desc "Testing args"
task: :hello, :user, :message do |t, args|
  args.with_defaults(:message => "Thanks for logging on")
  puts "Hello #{args[:user]}. #{:message}"
end

Railsアプリケーションの現在の環境をロードすることもできます

desc "Testing environment"
task: :hello => :environment do 
  puts "Hello #{User.first.name}."
end

私がやりたいことは、変数と環境を持つことができることです

desc "Testing environment and variables"
task: :hello => :environment, :message do |t, args|
  args.with_defaults(:message => "Thanks for logging on")
  puts "Hello #{User.first.name}. #{:message}"
end

しかし、それは有効なタスク呼び出しではありません。誰も私がこれを達成する方法を知っていますか?

207
Will

TLDR;

task :t, [args] => [deps] 

元の回答

Rakeタスクに引数を渡すと、:needsオプションを使用して環境を要求できます。例えば:


desc "Testing environment and variables"
task :hello, :message, :needs => :environment do |t, args|
  args.with_defaults(:message => "Thanks for logging on")
  puts "Hello #{User.first.name}. #{args.message}"
end

以下の@Peiniauのコメントごとに更新

Rails> 3.1の場合

task :t, arg, :needs => [deps] # deprecated

使ってください

task :t, [args] => [deps] 
112
hgmnz

この古いトピックをフォローアップするだけです。現在のRakefileが(かなり前から)そこにあるべきだと思います。これは、現在の勝利の答え(hgimenez)のアップグレードされバグ修正されたバージョンです。

desc "Testing environment and variables"
task :hello, [:message]  => :environment  do |t, args|
  args.with_defaults(:message => "Thanks for logging on")
  puts "Hello #{User.first.name}. #{args.message}"   # Q&A above had a typo here : #{:message}
end

これを呼び出す方法です( http://guides.rubyonrails.org/v4.2/command_line.html#rake ):

  rake "hello[World]" 

複数の引数の場合、タスク宣言(task :hello, [:a,:b,:c]...)の配列にキーワードを追加し、カンマ区切りで渡します:

  rake "hello[Earth,Mars,Sun,Pluto]" 

注:引数の数はチェックされないため、奇数の惑星は除外されます:)

368
inger

完全を期すために、ここでは上記の docs の例を示します。

   task :name, [:first_name, :last_name] => [:pre_name] do |t, args|
     args.with_defaults(:first_name => "John", :last_name => "Dough")
     puts "First name is #{args.first_name}"
     puts "Last  name is #{args.last_name}"
   end

ノート:

  • もちろん、#with_defaults呼び出しを省略できます。
  • 引数が1つだけであっても、Arrayを使用する必要があります。
  • 前提条件はArrayである必要はありません。
  • argsRake::TaskArgumentsのインスタンスです。
  • tRake::Taskのインスタンスです。
59
mikezter

これに関する別の方法:OS環境変数を使用します。このアプローチの利点:

  • すべての依存するレーキタスクがオプションを取得します。
  • 構文は非常に単純であり、レーキDSLに依存していません。これは把握が難しく、時間の経過とともに変化します。

3つのコマンドラインオプションを必要とするrakeタスクがあります。呼び出し方法は次のとおりです。

$ rake eaternet:import country=us region=or agency=multco

それは非常にきれいで、シンプルで、bash構文だけです。これが私のレーキタスクです。また、非常にきれいで魔法なし:

task import: [:environment] do
  agency = agency_to_import
  puts "Importing data for #{agency}..."
  agency.import_businesses
end

def agency_to_import
  country_code = ENV['country'] or raise "No country specified"
  region_slug  = ENV['region']  or raise "No region specified"
  agency_slug  = ENV['agency']  or raise "No agency specified"
  Agency.from_slugs(country_code, region_slug, agency_slug)
end

この特定の例は、依存関係の使用を示していません。ただし、:importタスクが他のタスクに依存している場合、これらのオプションにもアクセスできます。しかし、通常のレーキオプションの方法を使用すると、そうではありません。

19
Dogweather

これらのソリューションは機能しますが、私の意見ではこれは非常に複雑です。

また、zshでこのようにすると、配列内の角かっこが '\'でエスケープされていない場合、エラーが発生します。

ARGV配列を使用することをお勧めします。ARGV配列は正常に機能し、はるかに単純で、エラーが発生しにくいものです。例えば:

namespace :my_example do
  desc "Something"
  task :my_task => :environment do
    puts ARGV.inspect
  end
end

それから

rake my_example:my_task 1 2 3

#=>  ["my_example:my_task", "1", "2", "3"]

留意する必要がある唯一のことは、ARGV [0]がプロセス名であるため、ARGV [1 ..- 1]のみを使用することです。

ソリューションの一部として:environmentを使用しないため、厳密に言えばこれは質問に答えないことを理解しています。しかしOPは、なぜ彼のユースケースにも適用されるかもしれないので、彼がその規定を含めた理由を述べませんでした。

10
Lonny Eachus