I’m using the Ruby Money gem in a multi-tenant (SaaS) Rails app, and am looking for a good way to make the Money.default_currency be set to an Account’s preference for each request. I have several currency-related models in the app that use the Money class.
I have everything working properly in development, but I’m just looking for some feedback on whether or not the solution with have repercussions in production.
Here’s what I did in my ApplicationController (irrelevant code removed for brevity):
class ApplicationController < ActionController::Base
before_filter :set_currency
private
def set_currency
Money.default_currency = Money::Currency.new(current_account.present? && current_account.currency.present? ?
current_account.currency : 'USD')
end
end
So the code above will set the default_currency class variable to the current account’s preference, or default back to ‘USD’ if there isn’t one.
By the way, here’s the relevant default_currency code in the Money class:
class Money
# Class Methods
class << self
# The default currency, which is used when +Money.new+ is called without an
# explicit currency argument. The default value is Currency.new("USD"). The
# value must be a valid +Money::Currency+ instance.
#
# @return [Money::Currency]
attr_accessor :default_currency
end
end
So, will this work as expected in a multi-user setting? Anything else I need to do?
Most rails apps don’t run in multithreaded mode – a given instance is only ever handling one request at a time (this is the default).
If your app was in multithreaded mode this would be dangerous –
Money.default_currencycould get changed halfway through a request by the new request that has just come in. If you did want to make this thread safe, you could use theThread.currenthash to have per thread values ofdefault_currency