Skip to content

Instantly share code, notes, and snippets.

@ArturT
Last active January 15, 2020 11:54
Show Gist options
  • Save ArturT/7a54f43b46ce2d9dc02cfabb8bfdcda6 to your computer and use it in GitHub Desktop.
Save ArturT/7a54f43b46ce2d9dc02cfabb8bfdcda6 to your computer and use it in GitHub Desktop.
Service Objects in Ruby. Related video https://www.youtube.com/watch?v=Ydvu9gcu_iw
class UserController
def create
if params[:ads_source] == 'facebook'
@user = UserCreator.build_for_fb(params)
elsif params[:ads_source] == 'linkedin'
@user = UserCreator.build_for_linkedin(params)
else
raise 'Invalid ad campaign'
end
end
end
describe UserController do
describe '#create' do
let(:params) do
{
email: '[email protected]',
first_name: 'Jan',
last_name: 'Kowalski'
}
end
it do
ga_api = instance_double(GoogleAnalyticsAPI)
expect(GoogleAnalyticsAPI).to receive(:new).and_return(ga_api)
mixpanel_api = instance_double(MixpanelAPI)
expect(MixpanelAPI).to receive(:new).and_return(mixpanel_api)
user_creator = instance_double(UserCreator)
expect(UserCreator).to receive(:new).with(ga_api, mixpanel_api).and_return(user_creator)
user = double
expect(user_creator).to receive(:call).with(params).and_return(user)
post :create, params: params
end
end
end
class UserCreator
def self.build_for_linkedin(params)
new(LinkedInAPI.new).call(params)
end
def self.build_for_fb(params)
new(FacebookAPI.new).call(params)
end
def initialize(stats_api)
@stats_api = stats_api
end
def call(params)
user = User.create(
email: params[:email],
name: full_name(params)
)
stats_api.send_event('user_created', params)
user
end
private
attr_reader :stats_api
def full_name(params)
params[:first_name] + params[:last_name]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment