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/
@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
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!
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
log_acceptance(invite, current_user) UserMailer.welcome(current_user).deliver_later AdminMailer.invited(current_user).deliver_later redirect_to somewhere_else_path end end