我有一个rake任务,需要将一个值插入多个数据库。
我想从命令行或从另一个rake任务中将这个值传递给rake任务。
我该怎么做呢?
我有一个rake任务,需要将一个值插入多个数据库。
我想从命令行或从另一个rake任务中将这个值传递给rake任务。
我该怎么做呢?
当前回答
我在这两个网站上找到了答案:Net Maniac和Aimred。
您需要拥有版本> 0.8的rake才能使用这种技术
正常的rake任务描述如下:
desc 'Task Description'
task :task_name => [:depends_on_taskA, :depends_on_taskB] do
#interesting things
end
要传递参数,需要做三件事:
在任务名称之后添加参数名称,以逗号分隔。 将依赖项放在最后,使用:needs =>[…] 把|t, args|放在do后面。(t为本次任务的对象)
要访问脚本中的参数,请使用args.arg_name
desc 'Takes arguments task'
task :task_name, :display_value, :display_times, :needs => [:depends_on_taskA, :depends_on_taskB] do |t, args|
args.display_times.to_i.times do
puts args.display_value
end
end
要从命令行调用此任务,请将[]s中的参数传递给它
rake task_name['Hello',4]
将输出
Hello
Hello
Hello
Hello
如果你想从另一个任务调用这个任务,并给它传递参数,使用invoke
task :caller do
puts 'In Caller'
Rake::Task[:task_name].invoke('hi',2)
end
然后命令
rake caller
将输出
In Caller
hi
hi
我还没有找到一种方法来传递参数作为依赖的一部分,如下代码中断:
task :caller => :task_name['hi',2]' do
puts 'In Caller'
end
其他回答
如果你想传递命名参数(例如使用标准OptionParser),你可以使用这样的东西:
$ rake user:create -- --user test@example.com --pass 123
注意——,这是绕过标准Rake参数所必需的。应该适用于Rake 0.9。X, <= 10.3.x。
更新的Rake已经改变了对——的解析,现在你必须确保它没有传递给OptionParser#parse方法,例如使用parser.parse!(ARGV[2..-1])
require 'rake'
require 'optparse'
# Rake task for creating an account
namespace :user do |args|
desc 'Creates user account with given credentials: rake user:create'
# environment is required to have access to Rails models
task :create do
options = {}
OptionParser.new(args) do |opts|
opts.banner = "Usage: rake user:create [options]"
opts.on("-u", "--user {username}","User's email address", String) do |user|
options[:user] = user
end
opts.on("-p", "--pass {password}","User's password", String) do |pass|
options[:pass] = pass
end
end.parse!
puts "creating user account..."
u = Hash.new
u[:email] = options[:user]
u[:password] = options[:pass]
# with some DB layer like ActiveRecord:
# user = User.new(u); user.save!
puts "user: " + u.to_s
puts "account created."
exit 0
end
end
exit将确保额外的参数不会被解释为Rake任务。
参数的快捷方式也可以工作:
rake user:create -- -u test@example.com -p 123
当rake脚本看起来像这样时,也许是时候寻找另一种工具来实现这一点了。
选项和依赖项需要在数组中:
namespace :thing do
desc "it does a thing"
task :work, [:option, :foo, :bar] do |task, args|
puts "work", args
end
task :another, [:option, :foo, :bar] do |task, args|
puts "another #{args}"
Rake::Task["thing:work"].invoke(args[:option], args[:foo], args[:bar])
# or splat the args
# Rake::Task["thing:work"].invoke(*args)
end
end
Then
rake thing:work[1,2,3]
=> work: {:option=>"1", :foo=>"2", :bar=>"3"}
rake thing:another[1,2,3]
=> another {:option=>"1", :foo=>"2", :bar=>"3"}
=> work: {:option=>"1", :foo=>"2", :bar=>"3"}
注意:变量任务是任务对象,除非你知道/关心Rake内部,否则没有多大帮助。
RAILS的注意:
如果从Rails运行任务,最好通过添加=> [:environment]来预加载环境,这是一种设置依赖任务的方法。
task :work, [:option, :foo, :bar] => [:environment] do |task, args|
puts "work", args
end
我喜欢参数传递的“querystring”语法,特别是当有很多参数要传递时。
例子:
rake "mytask[width=10&height=20]"
“querystring”是:
width=10&height=20
警告:注意语法是rake“mytask[foo=bar]”而不是rake mytask["foo=bar"]
当在rake任务中使用Rack::Utils进行解析时。parse_nested_query,得到一个哈希值:
=> {"width"=>"10", "height"=>"20"}
(最酷的事情是你可以传递哈希和数组,更多如下)
以下是如何实现这一点:
require 'rack/utils'
task :mytask, :args_expr do |t,args|
args.with_defaults(:args_expr => "width=10&height=10")
options = Rack::Utils.parse_nested_query(args[:args_expr])
end
下面是我在delayed_job_active_record_threading gem中使用的一个更扩展的示例:
bundle exec rake "dj:start[ebooks[workers_number]=16&ebooks[worker_timeout]=60&albums[workers_number]=32&albums[worker_timeout]=120]"
以与上面相同的方式解析,使用环境依赖项(为了加载Rails环境)
namespace :dj do
task :start, [ :args_expr ] => :environment do |t, args|
# defaults here...
options = Rack::Utils.parse_nested_query(args[:args_expr])
end
end
给出以下选项
=> {"ebooks"=>{"workers_number"=>"16", "worker_timeout"=>"60"}, "albums"=>{"workers_number"=>"32", "worker_timeout"=>"120"}}
我在rake文件中使用了一个常规的ruby参数:
DB = ARGV[1]
然后我在文件底部去掉rake任务(因为rake将根据参数名查找任务)。
task :database_name1
task :database_name2
命令行:
rake mytask db_name
这感觉比我的var=foo ENV var和任务参数[blah, blah2]解决方案更干净。 存根有点麻烦,但如果您只有几个一次性设置的环境,那也不算太糟
实际上@Nick Desjardins的回答很完美。但只是为了教育:,你可以使用肮脏的方法:,使用ENV参数
task :my_task do
myvar = ENV['myvar']
puts "myvar: #{myvar}"
end
rake my_task myvar=10
#=> myvar: 10