如何将参数传入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 

但这不是一个有效的任务调用。 有谁知道我可以做到这一点?

将parameter passing给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] 

只是为了跟上这个老话题; 这里是我认为目前的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]" 

注:参数的数量没有被检查,所以奇怪的星球被遗漏:)

为了完整起见,这里是上面提到的文档的例子:

  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
  • argsRake::TaskArguments一个实例。
  • tRake::Task一个实例。

另一种方法是使用OS环境variables。 这种方法的好处:

  • 所有相关的rake任务都可以获得选项。
  • 语法要简单得多,而不依赖于很难计算出来并且随着时间而改变的rake DSL。

我有一个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任务依赖于其他人,他们也可以访问这些选项。 但使用正常的耙选方法,他们不会。

虽然这些解决scheme的工作,在我看来这是过于复杂。

另外,如果你在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]。

我意识到严格地说,这并不能回答这个问题,因为它没有把环境作为解决scheme的一部分。 但是OP没有说明为什么把这个规定包括在内,所以可能还是适用于他的用例。