Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ActiveJob: A Service Oriented Architecture?

ActiveJob: A Service Oriented Architecture?

RailsConf 2015

Andy Croll

April 23, 2015
Tweet

More Decks by Andy Croll

Other Decks in Programming

Transcript

  1. WHEN TO USE? • The action is complex • The

    action reaches across multiple models • The action interacts with an external service • The action is not a core concern of the underlying model blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/
  2. CONVENTIONS • app/services/ • Verbs for naming • Typically one

    public method per class • Do one ‘business thing’
  3. class AcceptInvite def initialize(invite, user) @invite = invite @user =

    user end def accept invite.accept(@user) log_acceptance(@invite, @user) UserMailer.welcome(@user).deliver AdminMailer.invited(@user).deliver end end
  4. Invite::Accept = Struct.new(:invite, :user) do def run invite.accept(user) log_acceptance(invite, user)

    UserMailer.welcome(user).deliver AdminMailer.invited(user).deliver end end
  5. class InviteAccepterService def initialize(invite, user, logger = MyLogger.new) @invite, @user,

    @logger = invite, user, logger end def process invite.accept(@user) log_acceptance(@invite, @user) UserMailer.welcome(@user).deliver AdminMailer.invited(@user).deliver end def log_acceptance @logger.acceptance(@invite, @user) end end
  6. class AcceptInvite < ActiveJob::Base def perform(invite, user) invite.accept(user) log_acceptance(invite, user)

    UserMailer.welcome(user).deliver_now AdminMailer.invited(user).deliver_now end end LOOK!
  7. SERVICES • The action is complex • The action reaches

    across multiple models • The action interacts with an external service • The action is not a core concern of the underlying model
  8. JOBS • The action is complex • The action reaches

    across multiple models • The action interacts with an external service • The action is not a core concern of the underlying model
  9. SERVICES & JOBS • app/services/ • Verbs • Typically one

    public method per class • Do one ‘business thing’ • app/jobs/ • Verbs • One ‘perform’ method defined per class • Do one ‘business thing’ • Async or sync, bonus!
  10. class InviteController < ApplicationController def accept AcceptInvite.perform_now(Invite.find(params[:id]), current_user) redirect_to somewhere_else_path

    end end class AcceptInvite < ActiveJob::Base def perform(invite, user) invite.accept(user) log_acceptance(invite, user) UserMailer.welcome(user).deliver_now AdminMailer.invited(user).deliver_now end end
  11. class InviteController < ApplicationController def accept invite = Invite.find(params[:id] invite.accept(current_user)

    log_acceptance(invite, current_user) UserMailer.welcome(current_user).deliver_later AdminMailer.invited(current_user).deliver_later redirect_to somewhere_else_path end end