我有一个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

其他回答

在传递参数时,更好的选择是输入文件,这可以是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 

在上面的答案中,传递参数的方法是正确的。然而,要运行带有参数的rake任务,新版本的rails涉及到一个小技术问题

它将与rake“namespace:taskname['argument1']”一起工作

注意从命令行运行任务时使用的倒引号。

我喜欢参数传递的“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"}}

这里我不明白的一点是如何处理任意参数。如果你传递了任务定义中没有列出的参数,它们仍然可以在args.extras下访问:

task :thing, [:foo] do |task, args|
  puts args[:foo]     # named argument
  puts args.extras    # any additional arguments that were passed
end
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”)”