Skip to content

Instantly share code, notes, and snippets.

@nogtini
Forked from elight/dci_alt.rb
Created June 24, 2019 15:21
Show Gist options
  • Save nogtini/f3eae1d2c38a39bd5a1c82a547a901f4 to your computer and use it in GitHub Desktop.
Save nogtini/f3eae1d2c38a39bd5a1c82a547a901f4 to your computer and use it in GitHub Desktop.
DCI with delegation instead of extension
class User < ActiveRecord::Base
# ... lots of persistence stuff
end
class GitHubUserProvisioner < SimpleDelegator
def provision_with!(user_info, extra_user_hash)
self.github_login = extra_user_hash['login']
self.name = user_info['name']
self.email = user_info['email']
self.github_url = user_info['urls']['GitHub']
self.blog_url = user_info['urls']['Blog']
self.gravatar_id = extra_user_hash['gravatar_id']
self.location = extra_user_hash['location']
save!
end
end
# And, say, in your SessionController in your controller action
class SessionController < ApplicationController
def create
user = User.new
provisioner = GitHubUserProvisioner.new(user)
provisioner.provision_with!(*yank_oauth_stuff_off_request)
end
private
def yank_oauth_stuff_off_request
# ...
end
end
@nogtini
Copy link
Author

nogtini commented Jun 24, 2019

From the blog: http://evan.tiggerpalace.com/articles/2011/11/24/dci-that-respects-the-method-cache/

I’ve been toying with DCI lately. But the techniques spelled out to date here and here use Object.extend. Extending an object blows away the method cache, slightly reducing performance.

So, as I lazed in bed, reading this tweet while dreaming of turkey to come, it hits me: instead of implementing the Delegator pattern through extend, let’s just use an actual Delegator object.

Simple example below based on the usage of NewUserProvisioner within RubyPair.

Our good friend SimpleDelegator is defined in “delegate.rb” in stdlib, courtesy of James Edward Gray II.

@nogtini
Copy link
Author

nogtini commented Jun 24, 2019

@nogtini
Copy link
Author

nogtini commented Aug 14, 2019

A book on DCI & Ruby: http://clean-ruby.com/

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