我有一个rake任务,需要将一个值插入多个数据库。
我想从命令行或从另一个rake任务中将这个值传递给rake任务。
我该怎么做呢?
我有一个rake任务,需要将一个值插入多个数据库。
我想从命令行或从另一个rake任务中将这个值传递给rake任务。
我该怎么做呢?
当前回答
我不知道如何传递args和:environment,直到我解决了这个问题:
namespace :db do
desc 'Export product data'
task :export, [:file_token, :file_path] => :environment do |t, args|
args.with_defaults(:file_token => "products", :file_path => "./lib/data/")
#do stuff [...]
end
end
然后我这样调用:
rake db:export['foo, /tmp/']
其他回答
如果你懒得记参数位置是什么你想做一些类似ruby参数哈希的东西。您可以使用一个参数传入一个字符串,然后将该字符串正则化为一个选项散列。
namespace :dummy_data do
desc "Tests options hash like arguments"
task :test, [:options] => :environment do |t, args|
arg_options = args[:options] || '' # nil catch incase no options are provided
two_d_array = arg_options.scan(/\W*(\w*): (\w*)\W*/)
puts two_d_array.to_s + ' # options are regexed into a 2d array'
string_key_hash = two_d_array.to_h
puts string_key_hash.to_s + ' # options are in a hash with keys as strings'
options = two_d_array.map {|p| [p[0].to_sym, p[1]]}.to_h
puts options.to_s + ' # options are in a hash with symbols'
default_options = {users: '50', friends: '25', colour: 'red', name: 'tom'}
options = default_options.merge(options)
puts options.to_s + ' # default option values are merged into options'
end
end
在命令行中。
$ rake dummy_data:test["users: 100 friends: 50 colour: red"]
[["users", "100"], ["friends", "50"], ["colour", "red"]] # options are regexed into a 2d array
{"users"=>"100", "friends"=>"50", "colour"=>"red"} # options are in a hash with keys as strings
{:users=>"100", :friends=>"50", :colour=>"red"} # options are in a hash with symbols
{:users=>"100", :friends=>"50", :colour=>"red", :name=>"tom"} # default option values are merged into options
我在rake文件中使用了一个常规的ruby参数:
DB = ARGV[1]
然后我在文件底部去掉rake任务(因为rake将根据参数名查找任务)。
task :database_name1
task :database_name2
命令行:
rake mytask db_name
这感觉比我的var=foo ENV var和任务参数[blah, blah2]解决方案更干净。 存根有点麻烦,但如果您只有几个一次性设置的环境,那也不算太糟
namespace :namespace1 do
task :task1, [:arg1, :arg2, :arg3] => :environment do |_t, args|
p args[:arg1]
end
end
调用
rake namespace1: task1(“1”、“2”、“3”)
不需要在调用时提供环境
在ZSH中需要附上引号
rake namespace1: task1(“1”、“2”、“3”)”
选项和依赖项需要在数组中:
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"}}