Skip to content

Instantly share code, notes, and snippets.

@ryenski
Last active August 13, 2018 15:41
Show Gist options
  • Save ryenski/09b14d64b43230cdfa9835615711decb to your computer and use it in GitHub Desktop.
Save ryenski/09b14d64b43230cdfa9835615711decb to your computer and use it in GitHub Desktop.
# Let's simulate a DripService object that will give us some output:
class DripService
include ActiveModel::Model
attr_accessor :entry
def call
print "You passed in an entry: #{entry.email}"
end
end
# Let's also simulate an Entry object:
class Entry
include ActiveModel::Model
attr_accessor :email
end
entry = Entry.new(email: '[email protected]')
#<Entry:0x00007f9ca0818a00 @email="[email protected]">
# This is the end result that we're trying to achieve:
DripService.new(entry: entry).call
# You passed in an entry: [email protected]=> nil
# Now let's play with constantize:
# This will return a plain string.
# If you try to do DripService things to the string you'll get an error, because the string does not respond to 'new'
"DripService"
# => "DripService"
"DripService".new(entry: entry)
# NoMethodError (undefined method `new' for "DripService":String)
# Constantize tries to find a declared constant with the name specified in the string. It raises a NameError when the name is not in CamelCase or is not initialized.
DripService".constantize
# => DripService
# Initizlize a new DripService object:
"DripService".constantize.new(entry: entry)
# => #<DripService:0x007fea9fcfd2d0 @entry=#<Entry id: nil, email: nil, form_id: nil, created_at: nil, updated_at: nil>>
"DripService".constantize.new(entry: entry).call
# You passed in an entry: [email protected]=> nil
# Dynamically instantiating a class based on the provider name:
provider_name = "drip"
# => "drip"
# We need to capitalize the first letter:
"#{provider_name.titleize}"
# => "Drip"
# Construct a string that ends with "Service", since that's the name of our class:
"#{provider_name.titleize}Service"
# => "DripService"
# Now we can constantize that string to return an actual DripService object:
"#{provider_name.titleize}Service".constantize
# => DripService
"#{provider_name.titleize}Service".constantize.new(entry: entry)
# => #<DripService:0x007fea9fc659a8 @entry=#<Entry id: nil, email: nil, form_id: nil, created_at: nil, updated_at: nil>>
"#{provider_name.titleize}Service".constantize.new(entry: entry).call
# You passed in an entry: [email protected]=> nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment