docbrown/app/services/listings/create.rb
2022-01-21 09:27:10 +07:00

50 lines
1.5 KiB
Ruby

module Listings
# This service wraps listing purchses in a transaction which verifies that
# the purchaser has enough credits to complete this process.
class Create
# @param listing [Listing] an initialized but not yet persisted listing
# @param purchaser [User] the user attempting to purchase the listing
# @param cost [Integer] the number of credits the user has to spend
# @return [Listings::Create] the service itself, used for the success? check
def self.call(listing, purchaser:, cost:)
new(listing, purchaser, cost).call
end
def initialize(listing, purchaser, cost)
@listing = listing
@purchaser = purchaser
@cost = cost
@success = false
end
def call
ActiveRecord::Base.transaction do
# Subtract credits
enough_credits = Credits::Buyer.call(
purchaser: @purchaser,
purchase: @listing,
cost: @cost,
)
raise ActiveRecord::Rollback unless enough_credits
# Update the listing
@listing.bumped_at = Time.current
@listing.published = true
@listing.originally_published_at = Time.current
# Since we can't raise ActiveRecord errors in this transaction
# due to the fact that we need to display them in the :new view,
# we manually rollback the transaction if there are validation errors
raise ActiveRecord::Rollback unless @listing.save
@success = true
end
self
end
def success?
@success
end
end
end