Rails APIを使用してアプリを作成しています。
現在下記のようなagreementモデルがあります。
roomで話し合い、userとhostが合意したらagreementを作成できます。
agreementのupdate機能を追加した際に、自分自身に対しても時間帯(start_timeとfinish_time)の重複チェックをしてしまうため、room_idからroomを特定しroom.agreementがnilでない場合にroom.agreement.idを重複チェックの要素に入れ、自分自身を除いた重複チェックができるようにしました。
しかしモデルspecでテストを実行した際に、room = Room.find(room_id)の部分でidがないと怒られました。
パラメータを渡してないからだと思うのですが、ではどのようにしてモデルテストを記述したら良いのか分かりません。。。。。
リクエストspecに書き換えたほうがいいでしょうか?
ベストプラクティスをご教授お願い致します。
ruby
1# agreement.rb 2 3 belongs_to :user 4 belongs_to :host 5 belongs_to :room 6validate :duplication_of_work_hours_for_same_user 7 8def duplication_of_work_hours_for_same_user 9 room = Room.find(room_id) 10 if room.agreement.nil? 11 Agreement.where('finish_time >= ? && ? >= start_time && user_id = ?', start_time, finish_time, user_id).exists? 12 errors.add(:start_time, "userの勤務期間が他の契約と重複していますneeee。") 13 else 14 agreement = room.agreement 15 if Agreement.where('id != ? && finish_time >= ? && ? >= start_time && user_id = ?', agreement.id, start_time, finish_time, user_id).exists? 16 errors.add(:start_time, "userの勤務期間が他の契約と重複しています。") 17 end 18 end 19 end
ruby
18) Agreement start_time, finish_time 1時間なら有効 2 Failure/Error: room = Room.find(room_id) 3 4 ActiveRecord::RecordNotFound: 5 Couldn't find Room without an ID 6 # ./app/models/agreement.rb:33:in `duplication_of_work_hours_for_same_user' 7 # ./spec/models/agreement_spec.rb:58:in `block (3 levels) in <top (required)>'
ruby
1it "1時間ちょうどなら有効" do 2 agreement = build(:agreement, finish_time: Time.current + 25.hour) 3 expect(agreement).to be_valid 4 end
ruby
1FactoryBot.define do 2 factory :agreement do 3 association :user 4 association :host 5 association :room 6 start_time { Time.current + 24.hour } 7 finish_time { Time.current + 32.hour } 8 state { 0 } 9 end 10end
ruby
1 2# 3このコードで解決しました。 4it "ちょうど1時間なら有効" do 5 agreement = build(:agreement, room: room, user: room.user, host: room.host, finish_time: Time.current + 25.hour) 6 expect(agreement).to be_valid 7 end
そして
ruby
1if room.agreement.nil? 2 Agreement.where('finish_time >= ? && ? >= start_time && user_id = ?', start_time, finish_time, user_id).exists? 3 errors.add(:start_time, "userの勤務期間が他の契約と重複していますneeee。") 4 else 5 6ここにifをつけ忘れていたこともややこしくしていました泣泣 7正しくは 8 9if room.agreement.nil? 10 if Agreement.where('finish_time >= ? && ? >= start_time && user_id = ?', start_time, finish_time, user_id).exists? 11 errors.add(:start_time, "userの勤務期間が他の契約と重複していますneeee。") 12 end 13 else 14 15に修正しました
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/29 06:15