環境
Rails 6.1.3.1
ruby 2.7.1
mysql Ver 8.0.26
前提
(1)User -> (多)Attendance
before
create_or_update_time!はざっくり言うと
・idがなかったら新規登録
・idと時間の指定があったら特定して更新
・idはあるが時間が指定がなかったら削除
を行うメソッド。
この場合、create_or_update_time!メソッドに引数を必要な分3つのみ(parameter[:punch_in]とparameter[:date]とparameter[:type])渡している。
引数が3つというのが少し多い気もするが、必要な分の引数を渡す方法で一見良いような気がする。
parameter = {
id: employee.id,
punch_in: { id: 1, value: '11:30' },
type: 'home',
date: '2022/10/01'
month: '2022-10',
}
create_or_update_time!(parameter[:punch_in], parameter[:date], parameter[:type])
# models/user.rb
def create_or_update_time!(parameter, date, type)
time = parameter[:value]
attendance = attendances.build(type: type, date: date) if parameter[:id].blank?
attendance = attendances.find(parameter[:id]) if parameter[:id].present?
attendance.update!(punched_at: "#{attendance.date} #{time}".in_time_zone) if time.present?
attendance.destroy! if time.blank?
end
after
create_or_update_time!に引数parameterをまるごと渡した。
理由は、
beforeの第1引数parameterが入れ子になっており一段階取り出す必要があるが、第2引数dateと第3引数typeはparameterの値をそのまま使っているため。
3つある引数のうち、1つはもう一段階取り出すのが感覚的に気持ち悪い感じがするのと、使う側が分かりづらい。
引数は必要な分だけ最小限渡すほうがいいと思っていたが、上記の場合は引数のオブジェクトをまるごと渡す方がわかりやすくていい。
parameter = {
id: employee.id,
punch_in: { id: 1, value: '11:30' },
type: 'home',
date: '2022/10/01'
month: '2022-10',
}
create_or_update_time!(parameter)
# models/user.rb
def create_or_update_time!(parameter)
time = parameter[:value]
attendance = attendances.build(type: parameter[:type], date: parameter[:date]) if parameter[:id].blank?
attendance = attendances.find(parameter[:id]) if parameter[:id].present?
attendance.update!(punched_at: "#{attendance.date} #{time}".in_time_zone) if time.present?
attendance.destroy! if time.blank?
end