Я думаю, что было бы разумно использовать пользовательский метод проверки, о котором вы можете прочитать в руководстве . Это может выглядеть примерно так:
class Item < ApplicationRecord
has_many :reservations
before_save :check_for_reservations
validate :okay_to_archive
def okay_to_archive
if !item.active && reservations.where("start_date >= ?", Date.today).any?
errors.add(:active, "can't be set to false when there are future reservations")
end
end
end
!item.active
проверяет, является ли атрибут active
не true
(nil
или false
). И reservations.where("start_date >= ?", Date.today).any?
проверяет, есть ли какие-либо ассоциированные reservations
, которые имеют start_date
, который приходит после сегодняшнего дня. Итак, вместе:
if !item.active && reservations.where("start_date >= ?", Date.today).any?
...
end
они проверяют, является ли item
неактивным с будущими бронированиями. Если это так, то ошибка записывается в errors
:
errors.add(:active, "can't be set to false when there are future reservations")
и при попытке сделать @item.save
вы получите ошибку проверки.
def archive
@item = Item.find(params[:id])
@item.active = false
if @item.save
flash[:notice] = "Item been archived..."
else
flash[:alert] = "Something went wrong..."
end
redirect_back(fallback_location: request.referer)
end
Код не проверен, но должен быть закрыт.