196

この質問にはすでに答えがあります。

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

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

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


  • インガーの新しい回答を受け入れるように更新してください。 - mahemoff

5 답변


106

TLDR;

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

元の答え

レーキタスクに引数を渡すとき、: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] 


  • 最新のドキュメントでは:needs「この形式は互換性のためにまだサポートされていますが、使用はお勧めできません。」 (私はこれは将来のブラウザについてのみ言及します:needsサポートされなくなりました。このセクションは、「廃止予定のタスクパラメータフォーマット」と呼ばれています...) - Telemachus
  • そのコードのバグ:" Hello#{User.first.name}を追加しました。 #{:message}" ...これは、「ログオンしていただきありがとうございます」ではなく「メッセージ」だけを出力します。修正:#{args.message}の最後のサブシティを修正しました。 - inger
  • Rails 3.1のタスク:t、arg、:needs => [deps]'推奨されていません。 ' task:t、[args] =>を使用してください。 [deps]'代わりに。 - Peiniau
  • 例を挙げて前のコメントを明確にするために、私はこれがうまくいくと信じる。task :hello, [:message] => [:environment] do |t, args|。 - Jason Swett
  • 追加の説明:複数の引数を渡すtask :hello, [:message1, :message2] => [:environment] do |t, args|動作し、useを呼び出すrake hello['message #1','message #2']。警告:引数リストに平文が含まれているとrakeが失敗することがわかりました。rake hello['message #1', 'message #2'](コンマの後のスペースに注意してください)。 - Steve Wilhelm

354

この古いトピックをフォローアップするためだけにここに私が現在の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]" 

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


  • この答えは受け入れられているはずです。 - samvermette
  • 男...熊手はいつも私にとってとてもルビー色ではないと感じます。あなたの最初の推測は、それが実際にどのように機能するかということです。この構文は単なる奇妙なものです。 < / rant> - Brian Armstrong
  • 2つの引数を送信するには、task:hello、[:arg1、::arg2] =>とします。 :environment do | t、args | - konyak
  • [:arg1、:arg2]の間にスペースを入れずに2つの引数を送信する - hbin
  • @hbinああ、これはRakefile内の宣言ではなくrakeを呼び出したときのことです(ChaseTのコメントで参照)。その場合はシェルの規則なので、1つのシェルワードとして記述してください。 (スペースなし)またはスペースを引用符で囲むか、次のように全体を引用符で囲みます。rake 'webp:convert["hello", "world"]'..警告:これを試したことはありませんが、うまくいくはずです。 - inger

57

完全を期して、ここからの例です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明らかに電話してください。
  • あなたが使用する必要がありますArrayあなたの議論のために、たとえ一つしかないとしても。
  • 前提条件は、である必要はありません。Array
  • argsのインスタンスですRake::TaskArguments
  • tのインスタンスですRake::Task


  • これはなぜ説明しますargs.empty?私に奇妙な結果を与えていました。argsハッシュのように見えますが、これはRake::TaskArguments。引数が渡されないときに特別な振る舞いをしたい場合は、#to_hashまたは#to_sチェックする前にargs空です。 - Dennis

18

これを代替する方法として、OSの環境変数を使う方法があります。このアプローチの利点:

  • すべての依存レーキタスクはオプションを得ます。
  • 構文ははるかに単純ですが、理解するのが難しく、時間とともに変化するレーキDSLには依存しません。

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

$ 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タスクは他人に依存していました、彼らはまたこれらのオプションへのアクセスを持っているでしょう。しかし、通常のレーキオプションの方法を使用すると、そうはなりません。


  • これは間違いなく環境変数ではありません。それですレーキ引数rakeはそれを環境変数として示していますが。大きな(そして実用的な)コンセプトの違いがあります!ご了承くださいcountry=us ruby -e "puts ENV['country']"と同じではありませんruby -e "puts ENV['country']" country=us(最初の環境変数と2番目の引数)。 - Djunzu

6

これらの解決策は機能しますが、私の意見ではこれは非常に複雑です。

また、zshでこのようにすると、配列の大括弧が '\'でエスケープされていないとエラーになります。

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は、なぜ彼がその規定を含めたのかを述べなかったので、それは彼のユースケースにも当てはまるかもしれません。


  • :environmentRailsアプリケーションコードをロードするために必要です。そして、私が手に入れるRailsアプリでそれを試してみます:["my_example:my_task", "1", "2", "3"] rake aborted! Don't know how to build task '1' (see --tasks) - Djunzu
  • これはまさに私が探していたものです - Paul Brunache

リンクされた質問


関連する質問

最近の質問