前提条件
Rails 5.2.4.2
インポートするcsvファイル:house_data.csv
house_data.csv
first_name,last_name,city,num_of_people,has_child
Carolyn,Flores,London,2,Yes
Jennifer,Martinez,Cambridge,3,No
...
手順
コントローラ/モデルの作成
terminal
rails g controller Houses
rails g model User first_name:string last_name:string city:string
num_of_people:integer has_child:string
rails db:migrate
ruby標準ライブラリcsvを追加
config/application.rb
require 'rails/all'
require 'csv'
gemの追加
csvファイルを読み込むためのgem roo
を追加する。
Gemfile
gem 'roo'
terminal
$ bundle install
ビューにcsvアップロードのためのフィールドを追加
app/views/houses/index.html.haml
= form_tag import_houses_path, multipart: true do
= file_field_tag :file
= submit_tag "インポート"
%table
%thead
%tr
%th
ID
%th
FirstName
%th
Lastname
%th
City
%th
num_of_people
%th
has_child
%tbody
- @houses.each do |house|
%tr
%td
= house.id
%td
= house.first_name
%td
= house.last_name
%td
= house.city
%td
= house.num_of_people
%td
= house.has_child
コントローラにアクションを追加
app/controllers/houses_controller.rb
def import
House.import(params[:file])
redirect_to houses_url
end
ルーティングを設定
config/routes.rb
Rails.application.routes.draw do
resources :houses do
collection { post :import }
end
end
ルーティング確認
terminal
% rails routes
Prefix Verb URI Pattern Controller#Action
import_houses POST /houses/import(.:format) houses#import
houses GET /houses(.:format) houses#index
POST /houses(.:format) houses#create
new_house GET /houses/new(.:format) houses#new
edit_house GET /houses/:id/edit(.:format) houses#edit
house GET /houses/:id(.:format) houses#show
PATCH /houses/:id(.:format) houses#update
PUT /houses/:id(.:format) houses#update
DELETE /houses/:id(.:format) houses#destroy
モデルにimportメソッドを記載
app/models/house.rb
class House < ApplicationRecord
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
house = find_by(id: row["id"]) || new
house.attributes = row.to_hash.slice(*updatable_attributes)
house.save
end
end
def self.updatable_attributes
["id", "first_name", "last_name", "city", "num_of_people", "has_child"]
end
end
結果
参考文献