ハイパーニートプログラマーへの道

頑張ったり頑張らなかったり

【Ruby on Rails】 スクリプトでActiveRecordを使ってバッチ処理

単純にスクリプト置いて、それをrunnerで実行、というところまではできたんですが、DBにアクセスしたいなと。

ActiveRecord使うとな?


app配下にbatchディレクトリを作って、そこにスクリプトを用意しました。
たいていlib配下らしいですが、その前に作ってもうた。

app/batch/sample.rb

@authors = Author.all

p @authors
$ rails runner batch/sample.rb 
#<ActiveRecord::Relation [#<Author id: 1, name: "ジャレド ダイアモンド">, #<Author id: 2, name: "倉骨 彰">, #<Author id: 3, name: "夏川 賀央">, #<Author id: 4, name: "ジャック・D. シュワッガー">, #<Author id: 5, name: "塩野 七生">]>

runnerコマンドで実行。DBにアクセスして、ずらずらーとレコードを出すだけです。

ハマった箇所

はじめは

RailsのscriptからActiveRecord使う【Rails3】【SQLite】【ActiveRecord】【バッチ処理】 - DRYな備忘録

を参考に

# 対象とするモデル
require 'app/models/author'

@authors = Author.all

p @authors

requireで対象となるモデルを呼ぼうとしてました。

この記事でも同様のことが書かれています。

ActiveRecord を利用するバッチ - わからん

しかし、エラーが出ます。

/home/noriyo_tcp/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:247:in `require': cannot load such file -- /home/noriyo_tcp/workspace/Project/app/models/author (LoadError)
  from /home/noriyo_tcp/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:247:in `block in require'
   from /home/noriyo_tcp/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:232:in `load_dependency'
  from /home/noriyo_tcp/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:247:in `require'
# (以下ずらずらーと)

そんなファイルはロードできないよと。んー。

# 対象とするモデル
require "#{Rails.root}/app/models/author"

@authors = Author.all

p @authors

これでも同じ。デスヨネー

config/application.rbでの設定

Rubyのバッチ処理でActiveRecordを使ってモデルクラス経由でのDB接続方法 - hachinoBlog

Ruby - ActiveRecord つかった Script の書き方まとめ - Qiita

を参考に

config.autoload_paths += %W(#{config.root}/batch)
config.autoload_paths += Dir["#{config.root}/batch/**/"]

を加えてみましたがダメ。

結論

Rails 4.0 - cannot load such file -- active_support/memoizable (LoadError) · Issue #133 · waynerobinson/xeroizer · GitHub

ここに似たようなことが書いてありました。Rails4.0にアップグレードしたらLoadErrorでると。

Rails 4.0 - cannot load such file -- active_support/memoizable (LoadError) · Issue #133 · waynerobinson/xeroizer · GitHub

それに対する答えが

https://github.com/waynerobinson/xeroizer/issues/133#issuecomment-37724213

The latest head version should work as it doesn't require this anymore.

require要らないよ、みたいな。

というわけで

@authors = Author.all

p @authors

単純にこうしたら通りました。ついでに

config.autoload_pathsの箇所も削ってみましたが大丈夫でした。


Rails4 で lib ディレクトリの自作ライブラリを autoload | EasyRamble

自作でライブラリやモジュールを作成した場合は、autoload_pathsを通す必要がありそうです。

Auto-loading lib files in Rails 4 - Stack Overflow

(ここではlibに通しています)

config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]

の代わりに

config.autoload_paths << Rails.root.join('lib')

これでもいける。