Reputation: 3029
I am looking for a clean way to have different behavior depending on whether we are in the test, development, staging, or production environment.
My question is general but the best specific example I have is sending notifications. Let's say I have a function in my User model object called notify
def notify(message)
#send a notification to the user (differs depending on the environment)
end
In the test environment I would like to use a mock object that just saves the notifications to a file. In the staging and production environments I would like to use a PushNotification object which actually sends API requests to a third party service. I need to use a different api key for each environment.
I was thinking I would create a folder at lib/notifiers and create a file_notifier.rb and a push_notifier.rb. I don't know where (what files) and how I would initialize the right notifier. Any ideas?
Thanks!
Upvotes: 0
Views: 166
Reputation: 80140
For starters, I'm going to be a bit of a whiny bitch — you don't have a function, but a method. A method, you see, is invoked on a receiver object. Why does this matter? Because if you think hard about it, it reveals the culprit of the difficulty you're having:
So the first step to solving your problem is to create an object that handles notifications and can be independently configured to behave appropriately based on the environment. Note that this object should not itself know about or care about the environment, but should be configurable such that you can easily mock it in development, which could happen either in your development.rb
file or in an initializer (perhaps called configure_notifier.rb
that will configure it for whichever environment).
As far as using different API keys, well, that's a separate issue entirely — you really don't want to store these in your repository, and the generally-accepted way of doing this is to configure the environment you're running in to maintain them. For Heroku, as a popular example, you could run heroku config:add SOMESERVICE_API_KEY=abcdefg12345
and then access this in your configuration via ENV['SOMESERVICE_API_KEY']
.
Upvotes: 2