Slide 1

Slide 1 text

CSV出力 - Viewからやるか? 他からやるか?- @ksk1030 Otemachi.rb #10 / 2018.10.17

Slide 2

Slide 2 text

話すこと Rails におけるCSV出力 扱い 誰 責務か

Slide 3

Slide 3 text

結論

Slide 4

Slide 4 text

結論 今回 Viewでやりました

Slide 5

Slide 5 text

こと 発端

Slide 6

Slide 6 text

こと 発端 HTMLでテーブル表示しているも を CSVでダウンロードしたい

Slide 7

Slide 7 text

そういや同じプロジェクト内でCSV 出してたとこあったな...どれどれ?

Slide 8

Slide 8 text

そういや同じプロジェクト内でCSV 出してたとこあったな...どれどれ? あれ? Modelに書いてある? 出力 話だからView 方が良い で ?

Slide 9

Slide 9 text

Modelで実装 (app/controllers/company_controller.rb) class CompanyController < ApplicationController def index condition = (...) # 検索条件 records = Company.to_csv(condition) respond_to do |format| format.html format.csv do send_data records end end end end (app/models/company.rb) require 'csv' class Company < ApplicationRecord def to_csv(condition) csv = CSV.generate(:force_quotes => true) { |csv| csv << @records.first.keys @records.each do |r| csv << r end } csv.encode('Shift_JIS', undef: :replace) end end (app/controllers/company_controller.rb) class CompanyController < ApplicationController def index condition = (...) # 検索条件 @records = Company.where(condition) respond_to do |format| format.html format.csv do send_data render_to_string end end end end (app/views/company/index.csv.ruby) require 'csv' csv = CSV.generate(:force_quotes => true) { |csv| csv << @records.first.keys @records.each do |r| csv << r end } csv.encode('Shift_JIS', undef: :replace) Viewで実装

Slide 10

Slide 10 text

Modelで実装 (app/controllers/company_controller.rb) class CompanyController < ApplicationController def index condition = (...) # 検索条件 records = Company.where(condition) respond_to do |format| format.html format.csv do send_data records end end end end (app/models/company.rb) require 'csv' class Company < ApplicationRecord def to_csv(condition) csv = CSV.generate(:force_quotes => true) { |csv| csv << @records.first.keys @records.each do |r| csv << r end } csv.encode('Shift_JIS', undef: :replace) end end (app/controllers/company_controller.rb) class CompanyController < ApplicationController def index condition = (...) # 検索条件 @records = Company.where(condition) respond_to do |format| format.html format.csv do send_data render_to_string end end end end (app/views/company/index.csv.ruby) require 'csv' csv = CSV.generate(:force_quotes => true) { |csv| csv << @records.first.keys @records.each do |r| csv << r end } csv.encode('Shift_JIS', undef: :replace) Viewで実装 view 拡張子に .ruby を指定して ruby コードを記述 処理 ロジック自体 同じように書ける

Slide 11

Slide 11 text

なんでViewか? ・表示 ため 整形処理 ・レコード 整形について View で  いじちゃってる箇所もあった  ・Decorator噛ませたかった (LT後補足) 「サービスクラスとかで共通処理書く が良い で 」というご意見いただきました。 割とそ 通りだと思ってます。 ただ今回 、既存 ビジネスロジックが分散してえらいことになっていたこと、Decorator 処理を 噛ませたかったことからこ ような判断をしています。 本来なら根本からリファクタリングする が筋で ありますが、今回面倒な で見送りました一回死んできます そ 辺り 腰を据えて取り組めるタイミングで別途対応する、という判断になりました。

Slide 12

Slide 12 text

背景が変われ 違う選択肢も ・レコード 塊を汎用的にcsv化したい  場合 共通メソッドにしちゃうとか ・でもcsv側 都合で個別にいじりたい  要望出そうだから結局 view で持つが  良い気もしている...

Slide 13

Slide 13 text

結論

Slide 14

Slide 14 text

結論 今回 Viewでやりましたが CSV化がどう利用される かに 思いを馳せたい

Slide 15

Slide 15 text

結論 今回 Viewでやりましたが CSV化がどう利用される かに 思いを馳せたい って言うかAPI化したい

Slide 16

Slide 16 text

中谷 圭佑 (@ksk1030)  任天堂株式会社(2011/04〜2013/12)  ・人事  株式会社ORSO(2014/01〜)  ・エンジニア(サーバサイドがメイン)  ・経営企画 ◆Speaker Deck  ・https://speakerdeck.com/ksk1030m 自己紹介

Slide 17

Slide 17 text

We are hiring!

Slide 18

Slide 18 text

Thank you for listening !!