Design pattern: Service objects
- logics do not belong to either the controller or the model
- service object is a pattern that can help you separate business logic
- Re-usable & easier to test
Instead of
# app/controllers/bookings_controller.rb def create @booking = Booking.new(booking_params) if @booking.save UserMailer.notify_new_booking UserMailer.notify_admin ... redirect_to root_path else render :new end end
Use
# app/services/base_service.rb class BaseService def self.call(*args) new(*args).call end end
# app/services/booking_creator.rb class BookingCreator < BaseService def initialize(params) @params = params end def call booking = Booking.new(@params) notify_after_create_booking if booking.save booking end private def notify_after_create_booking UserMailer.notify_new_booking UserMailer.notify_admin end end
# app/controllers/bookings_controller.rb def create @booking = BookingCreator.call(booking_params) redirect_to root_path if @booking.persisted? end