簡単なTODOアプリに、CSVファイルからタスクを追加する機能を実装します。
手順は以下の記事で説明されているものとほとんど同じです。めちゃくちゃ参考になりました。
【Ruby on Rails】CSVインポート
##実装
タスク追加、編集、削除機能、ログイン機能などを持つTODOアプリにCSVアップロード機能を実装して行きます。
Ruby on Railsで簡単なアプリを作成
【Rails】ログイン機能を実装する
###rubyの標準ライブラリcsv
を追加
require 'csv'
###roo
というgemを追加
csvファイルを読み込むためのgemroo
を追加します。
gem 'roo'
$ bundle install
###タスク一覧画面にcsvアップロード用のフィールドを追加
<%= form_tag import_tasks_path, multipart: true do %>
<%= file_field_tag :file %>
<%= submit_tag "インポート" %>
<% end %>
###コントローラーにアクションを追加
Task.import(params[:file])
で使われているimport
メソッドは後ほど定義します。
def import
Task.import(params[:file])
redirect_to root_url
end
###ルーティングを設定
collection {post :import}
と書き込むことで、resources :tasks
で作成されるルーティング以外の、tasksコントローラーのアクションへのルーティングを追加することができます。
resources :tasks do
collection {post :import}
end
$ rails routes
.
.
import_tasks POST /tasks/import(.:format) tasks#import
.
.
import_tasks
という名前付きルートが追加されました。
###モデルにCSV読み込み、登録処理を実装
#importメソッド
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
# IDが見つかれば、レコードを呼び出し、見つかれなければ、新しく作成
task = find_by(id: row["id"]) || new
# CSVからデータを取得し、設定する
task.attributes = row.to_hash.slice(*updatable_attributes)
task.save
end
end
# 更新を許可するカラムを定義
def self.updatable_attributes
["title", "user_id"]
end
###動作確認
以下のようなファイルを用意します。
title,user_id
パンを買う,2
筋トレ,2
メルカリの発送,8
ティッシュを交換する,2
##ハマったポイント
・CSVファイル内にuser_idを記載しておらず、データベースへの登録時にエラーが発生していたところで少しハマりました。
##TODO
・TSVファイルも取り込めるようにする