Rails 用 Rails 的 rake 或 rails runner 执行批处理时,带多个参数大家是怎么做的?

newbie · 2015年06月23日 · 最后由 newbie 回复于 2015年06月26日 · 3976 次阅读

比如我要这样用一个批处理:

bundle exec rails runner MyTask hello --params1 '1' --params2 '2'

这时执行时会提示:

ERROR: "rails_runner help" was called with arguments ["--params1", "1", "--params2", "2"]
Usage: "rails_runner help [COMMAND]"

为什么会提示 rails_runner ?不加参数可以正常执行 hello 方法。


如果用 Thor ,可以专门做命令行接口,但把它放到 rails 的 lib/tasks 下似乎不能访问 Active Record,是这样吗?

thor 没问题,可以调用 Active Record。这样执行批处理:

./bin/rails runner MyTask hello Matz --from DHH

如果要深究的话,最好是去读一下源码,从源码中可以看出 runner 用的是 Ruby 的 OptionParser 处理 ARGV,且只预设处理了 -h-e 这两种参数。

https://github.com/rails/rails/blob/master/railties/lib/rails/commands/runner.rb

如果你需要传递参数给 runner,可以尝试通过环境变量的方式传递参数,然后自己通过 ENV 获取环境变量。

name1=value1 name2=value2 bundle exec rails runner MyTask hello

你的 hello 是这样的:

class TestRunner
 def self.hello(param1, param2)
    puts "#{param1}---#{params2}"
  end
end

Console:

$ rails runner "puts TestRunner.hello(1, 2)"

#3 楼 @lgn21st 谢谢。但我还是要用 thor 这种专门的命令行接口,它可以自由定义多个参数:

class MyCLI < Thor
  option :from
  option :yell, :type => :boolean
  desc "hello NAME", "say hello to NAME"
  def hello(name)
    output = []
    output << "from: #{options[:from]}" if options[:from]
    output << "Hello #{name}"
    output = output.join("\n")
    puts options[:yell] ? output.upcase : output
  end
end
$ ./cli hello --yell Yehuda --from "Carl Lerche"
FROM: CARL LERCHE
HELLO YEHUDA

$ ./cli hello Yehuda --from "Carl Lerche" --yell
FROM: CARL LERCHE
HELLO YEHUDA

#4 楼 @ruby_sky 这种方法也可以,但不够智能,比如如果想单独指定某个参数,用 --parma1 'a' --param2 'b' 就好些。

#5 楼 @newbie hello方法,参数变成一个 options 就可以了。

rake 任务的话

task :my_task, [:foobar] => :environment do |t, args|
  foo = args.foobar.to_i
  put foo
end

执行就这样bundle exec rake my_task[123456]

#8 楼 @zoker 谢谢关于 rake 的例子。要指定特定的 option 名称似乎 rake 就办不到了,只能以传参的形式。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号