Rails での例外処理 2
Rails での例外処理 2
Rails
での例外処理については、以前
Rails での例外処理 - hene.dev
にも書いていましたが、少し変更しました。
これは、管理画面でユーザーをインポートするときの処理です。
lib
じゃなくて、app/forms
にformオブジェクト
として作れば良かった。
ここに載せた実装は、多分良くない実装です。。
# lib/csv_reader.rb
module CsvReader
require 'csv'
def import_user(csv_path)
read_csv = CSV.read(csv_path, headers: true)
ActiveRecord::Base.transaction do
read_csv.each do |csv|
user = User.find_or_initialize_by(id: csv['ID'])
user.update!(user_attr(csv))
end
end
true
rescue ActiveRecord::RecordInvalid => e
error_messages = e.record.errors.full_messages.map { |error| "ID: #{e.record.id} の #{error}" }
Rails.logger.debug error_messages
error_messages
rescue ActiveRecord::RecordNotFound, ActiveHash::RecordNotFound => e
match = e.message.match(/^Couldn't find (\w+)/)
model_name = I18n.t('activerecord.models.' + match[1].underscore)
error_messages = "#{model_name} が間違っています"
Rails.logger.debug error_messages
error_messages
end
def user_attr(csv)
{
id: csv['ID'],
first_name: csv['名前'],
last_name: csv['苗字'],
age: csv['年齢'],
job: Job.find_by!(name: csv['仕事']),
company: Company.find_by!(name: csv['会社'])
}
end
end
ActiveRecord::RecordInvalid
ActiveRecord::RecordInvalid
は、
バリデーションに引っかかったときのエラーです。
ActiveRecord::RecordNotFound
find_by
: 見つからなかったときに nil
を返す。
find_by!
: 見つからなかったときに ActiveRecord::RecordNotFound
を返します。
ActiveHash::RecordNotFound
ActiveHash::RecordNotFound
は ActiveHash
版の ActiveRecord::RecordNotFound
です。
ActiveHash
は、active_hash
というgem
を使って、ActiveRecord
のように区分値情報を扱えるものです。 説明しづらいのですが便利です。
# app/controllers/users_controller.rb
# frozen_string_literal: true
class UsersController < ApplicationController
...
def import
csv_file = params[:csv_file]
if csv_file.present?
if csv_file.original_filename.include?('.csv')
@user = CsvReader.import_user(csv_file.path)
if @user == true
flash[:success] = 'インポートに成功しました'
else
flash[:danger] = ['インポートに失敗しました', *@user]
end
else
flash[:danger] = 'CSVファイル以外は対応していません'
end
else
flash[:danger] = 'ファイルが選択されていません'
end
redirect_to new_user_path
end
end
original_filename
original_filename
で、ファイル名を取れるので csv
かどうか判別している。
Rails での例外処理を調べてみて
プロを目指す人のための例外処理(再)入門 / #rubykansai 2018-01-13 - Speaker Deck を読んで、例外処理を全然わかってないことに気づきました。
上に書いたような処理は、業務エラー
で例外処理は原則として使わない方が良い。
こういったとき、成功
or 失敗
はメソッドの戻り値で表現する。
呼び出し側は必ず戻り値を検証する。
ActiveRecord::Rollback
で、明示的にロールバックさせることができる。
不必要に 例外処理
を使ってしまっていた。
例外処理
をなくして 業務エラー
に対処していきたい。
ActiveRecord::RecordInvalid
の部分とか、
例外処理を使わずに実装する場合のコード例 - プロを目指す人のための例外処理(再)入門 / #rubykansai 2018-01-13 - Speaker Deck
対応していきたいが、エラーメッセージをどうやって コントローラー側で取ればよいかまだわかっていない。
感想
プロを目指す人のためのRuby入門
持っているのに、読めてないので読みたい。
基本的なところが抜けているので、しっかり基礎から勉強していきたい。