I have approve event enum in Booking model. I have a before_validation in approve
in my model/booking.rb I added custom validation
include AASM
before_validation :item_availability, if: :approved?
enum status: [:pending, :approved, :rejected, :on_loan, :returned]
aasm column: :status, enum: true do
state :pending, initial: true
state :approved
state :rejected
state :on_loan
state :returned
event :approve do
transitions from: :pending, to: :approved
end
event :reject do
transitions from: :pending, to: :rejected
end
event :on_loan do
transitions from: :approved, to: :on_loan
end
event :returned do
transitions from: :on_loan, to: :returned
end
end
private
def item_availability
if item.quantity.to_f < quantity.to_f
errors.add(:base, "Not enough quantity for #{item.name} only #{item.quantity} left")
false
end
end
and in my controller, I'm calling the service
@service = Manage::BookingApprovalService.new({booking: @booking})
@service.run
app/services/manage/booking_approval_service
class Manage::BookingApprovalService < BaseService
attr_accessor :booking
def run
Booking.transaction do
booking.approve! // I confirmed that I'm getting the false here
booking.item.decrement!(:quantity, booking.quantity)
BookingsMailer.send_approval(booking).deliver_now
end
end
end
I'm getting false when I debug the booking.approve! because the quantity I have in booking is greater than the item quantity.
But from the service. the decrement! and send_approval mail is still invoking.
Why does the service doesn't rollback if I'm getting false from booking.approve!
The transaction block will rollback only if you raise an exception.
Docs: https://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html