我有一个rake任务,需要将一个值插入多个数据库。
我想从命令行或从另一个rake任务中将这个值传递给rake任务。
我该怎么做呢?
我有一个rake任务,需要将一个值插入多个数据库。
我想从命令行或从另一个rake任务中将这个值传递给rake任务。
我该怎么做呢?
当前回答
实际上@Nick Desjardins的回答很完美。但只是为了教育:,你可以使用肮脏的方法:,使用ENV参数
task :my_task do
myvar = ENV['myvar']
puts "myvar: #{myvar}"
end
rake my_task myvar=10
#=> myvar: 10
其他回答
如果你想传递命名参数(例如使用标准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脚本看起来像这样时,也许是时候寻找另一种工具来实现这一点了。
我不知道如何传递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/']
在传递参数时,更好的选择是输入文件,这可以是excel, json或任何你需要的,从那里读取数据结构和你需要的变量,包括变量名,因为是需要的。 读取文件可以有以下结构。
namespace :name_sapace_task do
desc "Description task...."
task :name_task => :environment do
data = ActiveSupport::JSON.decode(File.read(Rails.root+"public/file.json")) if defined?(data)
# and work whit yoour data, example is data["user_id"]
end
end
示例json
{
"name_task": "I'm a task",
"user_id": 389,
"users_assigned": [389,672,524],
"task_id": 3
}
执行
rake :name_task
选项和依赖项需要在数组中:
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
使用传统的参数样式运行rake任务:
rake task arg1 arg2
然后使用:
task :task do |_, args|
puts "This is argument 1: #{args.first}"
end
添加以下rake gem补丁:
Rake::Application.class_eval do
alias origin_top_level top_level
def top_level
@top_level_tasks = [top_level_tasks.join(' ')]
origin_top_level
end
def parse_task_string(string) # :nodoc:
parts = string.split ' '
return parts.shift, parts
end
end
Rake::Task.class_eval do
def invoke(*args)
invoke_with_call_chain(args, Rake::InvocationChain::EMPTY)
end
end