目標
開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina
前提
下記実装済み。
実装
1.Gemを導入
Gemfile
# 追記
gem 'roo'
ターミナル
$ bundle
2.application.rb
を編集
application.rb
require_relative 'boot'
require 'rails/all'
require 'csv' # 追記
Bundler.require(*Rails.groups)
module Bookers2Debug
class Application < Rails::Application
config.load_defaults 5.2
end
end
3.モデル編集
book.rb
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
book = find_by(id: row["id"]) || new
book.attributes = row.to_hash.slice(*updatable_attributes)
book.save!(validate: false)
end
end
def self.updatable_attributes
['id', 'title', 'body']
end
① インポートするデータに同じIDが見つかればそのレコードを呼び出し、見つかれなければ新しく作成する。
book = find_by(id: row["id"]) || new
② CSVファイルからデータを取得する。
book.attributes = row.to_hash.slice(*updatable_attributes)
③ バリデーションを通さずに保存する。
book.save!(validate: false)
④ CSVインポート時に受信するカラムを設定する。
def self.updatable_attributes
['id', 'title', 'body']
end
4.コントローラーを編集
books_controller.rb
def import
Book.import(params[:file])
redirect_to books_path
end
5.ルーティングを追加
routes.rb
resources :books do
collection { post :import }
end
6.ビューを編集
books/index.html.slim
= form_tag import_books_path, multipart: true do
= file_field_tag :file
br
= submit_tag "インポート", class: 'btn btn-success'