baronyan's blog

linux,macでruby、railsでの開発をしていく中で知ったこと、備忘的なことなどを書いていきます。

ActiveAdminをカスタマイズしてDBレコードのcsv書き出しと取り込みを簡単にできるようにしてみました。

Railsアプリの管理画面を簡単に作成できるActiveAdminというgemがあります。
このgemはかなり便利で、crud操作はもちろんのこと、便利な検索(Filter)や、
csvxmljsonでのダウンロード機能も提供してくれます。

さらにactive_admin_importableというgemをインストールすれば、
csvをアップロードすることでDBにレコードを追加することができます。

csv書き出しとcsv取り込み、この2つがあれば、
エンジニアではない人による管理業務など色々と便利になりますよね。

ところがデフォルトのcsvダウンロードだと外部キーがヘッダに含まれないという
仕様になっているようで、ダウンロードしたcsvをDBに(同一スキーマの他環境DBに、
または、レストアとして同DBに)読み込ませることはできません。

そこで、外部キーも含めた全カラムの情報がcsvに含まれるようにカスタマイズしてみました。

Rails_root/app/admin/モデル.rb
という形でモデルの管理ページを記述するのですが、
このファイルに次のように追記します。

追記前

	ActiveAdmin.register Book do
	index do |books|
	    ...
	  end
	  
	  show do |book|
	    ...
	  end
	end

追記後

	ActiveAdmin.register Book do
	  csv :force_quotes => false do
	    Book.column_names.each do |col|
	      column col.to_sym
	    end
	  end
	  
	  index do |books|
	    ...
	  end
	  
	  show do |book|
	    ...
	  end
	end

これで無事、Bookテーブルの全カラムを含んだcsvをダウンロードできるようになりました。
(ただし、ヘッダ内の外部キー名からは「_id」が強制的に削除される仕様のようです。)



次にcsv読み込みです。
active_admin_importableの基本的な使い方としては、
csv書き出し同様、Rails_root/app/admin/モデル.rb に次のように追記します。

	active_admin_importable do |model, hash|
	  arg = {}
	  Book.column_names.each do |col|
	    col_sym =  col.to_sym
	    arg[col_sym] = hash[col_sym]
	  end
	  model.create(arg)
	end

上で書いたように、書き出したcsvはヘッダの外部キー名から「_id」が消えている状態ですが、
次のようにすることでその差異を吸収できます。

	active_admin_importable do |model, hash|
	  arg = {}
	  Book.column_names.each do |col|
	    col_sym =  col.to_sym
	    col = col.gsub('_id', '')
	    col_sym_for_hash =  col.to_sym
	    arg[col_sym] = hash[col_sym_for_hash]
	  end
	  model.create(arg)
	end


以上がactive_adminとactive_admin_importableを用いた
DBレコードのcsv書き出しと読み込みの方法です。


かなり便利だと思います。是非使ってみてください!


追記:
csv書き出しは管理画面の左下に「csv」表記のリンクで表示されます。
csv読み込みは管理画面の右上に「Import モデル名s」表記のボタンで表示されます。

ActiveRecord経由でidを付け替える方法

book = Book.find(1)
book.id = 35
book.save

とするとidを変更できそうなものですが、uniqueness制約を付けている場合、
そのuniquenessカラム群がユニークであるにも関わらず、自分自身を指して
「uniquenessカラムが同じで別idのレコードが存在する」と更新を弾かれてしまします。

そんな場合には以下のようにすることで、更新することができます。

book = Book.find(1)
book.id = 35
book.update_all(["id = 1", "id = 35"])

gitでファイルの存在をなかったことにする

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch ファイル名' HEAD

してから、

git push --force origin master

で強制pushをすることで、最初からそのファイルのコミットがなかったことにできます。

(--cachedを付けるとワーキングファイルを残せます。)
(ディレクトリの場合はrmに-rfオプションを付けてください。)


参考ページ
Git の履歴からファイルを完全に削除する – git filter-branch | EasyRamble

railsのログのカラー表示(ANSIカラーコード)を止める

ログのカラー表示は見やすくてとても便利です。
ただ、stdoutではカラー表示されるのですが、logファイルをview等で見た場合、カラーコードが文字列として表示されてしまい、見づらいものとなります。

カラー表示を止めたい場合には、config/application.rbに次の行を追加します。

config.colorize_logging = false