Created
October 12, 2012 17:28
-
-
Save nicholasjhenry/3880386 to your computer and use it in GitHub Desktop.
An example of using Ruby Events Gem
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Example: | |
| # | |
| # submit_order = SubmitOrder.new(current_user, order) | |
| # submit_order.call | |
| # | |
| # Uses RubyEvents: https://github.com/nathankleyn/ruby_events | |
| # app/use_cases/submit_order.rb | |
| class SubmitOrder | |
| CannotAuthorizePayment = Class.new(StandardError) | |
| attr_reader :customer, :order | |
| def initialize(customer, order) | |
| @order, @customer = order, customer | |
| end | |
| def call | |
| order.events.listen(:submitted) do |order| | |
| payment_processor.authorize(order, card_on_file) | |
| cart.empty! | |
| end | |
| payment_processor.listen(:authorization_succeeded) do |transaction| | |
| order.paid!(card_on_file, transaction) | |
| end | |
| payment_processor.listen(:authorization_failed) do |transaction| | |
| raise CannotAuthorizePayment.new | |
| end | |
| order.events.listen(:paid) do |order| | |
| order.prepare_shipment! | |
| end | |
| order.events.listen(:shipment_prepared) do |order| | |
| inventory.update!(order.variants) | |
| send_notifications | |
| end | |
| order.submit! | |
| end | |
| private | |
| def send_notifications | |
| BuyerMailer.delay(:queue => 'email', :priority => 30).order_confirmation(order.id) | |
| end | |
| def cart | |
| Cart.new(order) | |
| end | |
| def payment_processor | |
| PaymentProcessor.new | |
| end | |
| def inventory | |
| Inventory.new | |
| end | |
| def card_on_file | |
| customer.card_on_file | |
| end | |
| end | |
| # app/models/order.rb | |
| class Order < ActiveRecord::Base | |
| # associations defined here | |
| def submit!(listeners) | |
| self.class.transaction do | |
| events.fire(:submitted, self) | |
| save! | |
| end | |
| end | |
| def paid!(credit_card, transaction) | |
| order.credit_card = credit_card | |
| order_purchased! | |
| payout_pending! | |
| create_payment(transaction_id: transaction.id) | |
| events.fire(:paid, self) | |
| end | |
| def prepare_shipment! | |
| create_shipment | |
| events.fire(:shipment_prepared, self) | |
| end | |
| private | |
| def add_shipment | |
| Shipment.build(order: self) | |
| end | |
| def add_payment(attributes) | |
| Payment.new(attributes.merge(order: self)) | |
| end | |
| end | |
| # app/models/cart.rb | |
| class Cart | |
| attr_reader :order | |
| def initialize(order) | |
| @order = order | |
| end | |
| def empty! | |
| order.cart_items.destroy_all | |
| end | |
| end | |
| # app/models/payment_processor.rb | |
| class PaymentProcessor | |
| def authorize(order) | |
| result = PaymentGateway.authorize(credit_card, order) | |
| if result.success? | |
| events.fire(:authorization_succeeded, result.transaction) | |
| else | |
| events.fire(:authorization_failed, result.transaction) | |
| end | |
| end | |
| end | |
| # app/models/inventory.rb | |
| class Inventory | |
| def update!(variants) | |
| variants.each { |item| item.decrement_count_on_hand } | |
| end | |
| end | |
| # app/models/shipment.rb | |
| class Shipment < ActiveRecord::Base | |
| def self.build(order) | |
| shipment_factory = ShipmentFactory.new(self) | |
| shipment_factory.build(order) | |
| end | |
| end | |
| # app/models/shipment_factory.rb | |
| class ShipmentFactory < SimpleDelegator | |
| def build(order) | |
| case | |
| when order.for_managed_account? | |
| build_managed_for(order) | |
| when order.has_sure_shop? | |
| build_managed_for(order) | |
| build_addressed_to_shophers_for(order) | |
| else | |
| build_unmanaged_for(order) | |
| end | |
| events.fire(:prepared, self) | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment