概要
Rails5で導入された、ApplicationRecordクラスに実装することにより、全モデルでシンプルなインポート機能を使えるようにする。
環境
- Ruby 2.3.1
- Rails 5.1.2
方法
activerecord-importを導入
インポートをとても楽にしてくれるactiverecord-importを導入します。(参考:【Rails】activerecord-import でデータを bulk-insert するのが超便利でイケメン河童になる)今回の話の本質ではないですが、すごい便利なので紹介がてら使います。
インストールは普通通り、下記をGemfileに追加してbundle installする。なお、active adminを導入している場合は既にインストールされているかもしれません。その場合は無視してください。
gem 'activerecord-import'
ApplicationRecordクラスに実装
Rails5から全てのモデルはApplicatonRecordクラスから継承されるようになりました。よって、全てのモデルで使いたいメソッドは、ApplicationRecordクラスに実装すれば呼び出すことができます。
今回は、インポートするためのメソッド simple_import メソッドを下記の様に実装します。
class ApplicationRecord < ActiveRecord::Base
def self.simple_import(path: '', col_sep: ',')
a = []
CSV.foreach(path, headers: true, col_sep: col_sep) do |r|
a << self.new(get_import_params(r))
end
import a # activerecord-importのメソッドです。
end
private
def self.get_import_params(row)
headers = row.headers & self.column_names # 存在するカラム名のみに限定する
headers.each_with_object({}) do |c, h|
h[c.to_sym] = row.field(c)
end
end
end
ちなみに、aはarray、rはrow, hはhash、cはcolの略のつもり。
使い方
モデル
- 例えば、idとnameとcolorカラムを持つFruitモデルを想定します。
class Fruit < ApplicationRecord
end
csvデータ
- インポートするcsvを用意します。
例えば、インポートするデータをdbフォルダ直下に用意します。
id,name,color,kansou
1,apple,red,oisii
2,banana,yellow,amai
1行目はヘッダーで、2行目以降がデータです。
インポートしたいカラムには 必ずカラム名と同じ名称 をつけてください。なお、存在しないカラム名はインポートされません。(この例ではkansou)
インポート
このcsvデータをインポートするためには、 Fruit.simple_import をするだけです。
例えば、rails consoleから下記の様にコマンドをうてばインポートされます。(ちゃんとkansouカラムは無視されます)
> Fruit.simple_import(path: 'db/input.csv', col_sep: ',')
以上