LoginSignup
7
9

More than 3 years have passed since last update.

【Rails】CSVインポート機能の実装

Posted at

目標

ezgif.com-video-to-gif.gif

開発環境

・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

前提

下記実装済み。

Slim導入
Bootstrap3導入
投稿機能実装

実装

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'
7
9
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9