LoginSignup
1
1

More than 5 years have passed since last update.

Railsのバッチではオプションパーサを使うべきではない

Posted at

Railsでバッチを実行する場合、runnerで以下のようにできる。

bundle exec rails runner Batches::Sample.function

値を渡したかったのでオプションをつけてみた。

バッチ本体
class Batches::Sample
  def self.function
    if ARGV.empty?
      puts "NO ID"
      return
    end
    my_id = nil
    argv = ARGV.dup
    argv.delete "--" if argv.include? "--"
    OptionParser.new do |parser|
      parser.on("-i", "--my_id MY_ID", Integer) { |v| my_id = v }
      parser.parse!(argv)
    end
    puts "SUCCESS"
  end
end
bundle exec rails runner Batches::Sample.function -- -i 1

バッチをcronで定期的に実行したい。wheneverというGemが便利。

every 1.hour do
  runner 'Batches::Sample.function'
end

これが

$ bundle exec whenever
0 * * * * /bin/bash -l -c 'cd /home/user/project && bin/rails runner -e development '\''Batches::Sample.function'\'' >> log/cron.log 2>&1'

## [message] Above is your schedule file converted to cron syntax; your crontab file was not updated.
## [message] Run `whenever --help' for more options.
$ bundle exec whenever --update-crontab
[write] crontab file updated

こうなって

/home/user/project/lib/batches/sample.rb:12:in `block in function': invalid option: -e (OptionParser::InvalidOption)
        from /home/user/project/lib/batches/sample.rb:10:in `new'
        from /home/user/project/lib/batches/sample.rb:10:in `function'
        from /home/user/project/vendor/bundle/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands/runner.rb:62:in `<top (required)>'
        from /home/user/project/vendor/bundle/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands/runner.rb:62:in `eval'
        from /home/user/project/vendor/bundle/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands/runner.rb:62:in `<top (required)>'
        from /home/user/project/vendor/bundle/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands/commands_tasks.rb:128:in `require'
        from /home/user/project/vendor/bundle/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands/commands_tasks.rb:128:in `require_command!'
        from /home/user/project/vendor/bundle/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands/commands_tasks.rb:95:in `runner'
        from /home/user/project/vendor/bundle/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
        from /home/user/project/vendor/bundle/ruby/2.1.0/gems/railties-4.1.10/lib/rails/commands.rb:17:in `<top (required)>'
        from bin/rails:4:in `require'
        from bin/rails:4:in `<main>'

ご覧の有様。

railsコマンドに対するオプションがバッチにも与えられてしまっているらしい。
対処法が無いか調べたがどうにもならず。
結局、値はハッシュを使って引数で渡すことにした。

bundle exec rails runner 'Batches::Sample.function(id: 1)'
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1