Skip to content

Instantly share code, notes, and snippets.

@robwilliams
Last active August 29, 2015 14:25
Show Gist options
  • Save robwilliams/ba23bb64125ae03fcb45 to your computer and use it in GitHub Desktop.
Save robwilliams/ba23bb64125ae03fcb45 to your computer and use it in GitHub Desktop.
Single action per controller ideas
# app/actions/cart/add_item.rb
class Cart::AddItem
include Interactor
include InteractorBroadcast
include Wisper::Publisher
delegate :item, :checkout, :variant_id, :quantity, to: :context
def call
fail_if_checkout_is_locked
fail_if_variant_does_not_exist
fail_if_out_of_stock
build_item
set_item_quantity
set_success_message
reduce_quantity_to_available_stock
item.save
broadcast(:checkout_total_changed, checkout)
end
private
# ...
end
# app/controllers/cart/add_item_controller.rb
class Cart::AddItemController < ApplicationController
def create
action = Cart::AddItem.new(
checkout: current_checkout,
quantity: quantity,
variant_id: variant_id,
)
action.subscribe(EnsureValidShippingMethod)
action.on(:success) do |result|
flash[:success] = t(
result.message,
name: result.item.name,
quantity: result.item.quantity
)
redirect_to cart_path
end
action.on(:failure) do |result|
flash[:error] = t(result.message)
redirect_back(default: cart_path)
end
action.run
end
private
def quantity
params[:checkout_item][:quantity]
end
def variant_id
params[:checkout_item][:variant_id]
end
end
get 'cart' => 'cart#show', as: :cart
post 'cart/add' => 'cart/add_item#create', as: :cart_add
delete 'cart/remove' => 'cart/remove_item#destroy', as: :cart_remove
put 'cart/apply_coupon' => 'cart/apply_coupon#update', as: :cart_apply_coupon
@robwilliams
Copy link
Author

Note that I've kept the restful method names so you can see at a glance how the action will respond. I also haven't moved 'cart#show' into the namespace yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment