如何将参数传入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
。 -
args
是Rake::TaskArguments
一个实例。 -
t
是Rake::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没有说明为什么把这个规定包括在内,所以可能还是适用于他的用例。