Usually in Ruby & Rails there's an application-specific configuration
file (not XML, but Ruby).
A little improvisation:
# config.rb
ACTIVE_MERCHANT_GATEWAYS = [ SomeKindOfGateway,
SomeOtherKindOfGateway ]
# view, Settings page or something
# I don't remember, but something like this:
select_tag :current_gateway,
options_for_select(ACTIVE_MERCHANT_GATEWAYS.map do |gw| [gw.name,
gw.name] end
# controller,
def set_current_gateway
gateway = params[:current_gateway].constantize # this variable HOLDS
THE CLASS ITSELF
GatewayBase.current = gateway
end
This is really untested and I don't think I would implement it this
way (I don't have enough information to decide that), but let me
explain:
* Classes are just objects. You can store them in an Array.
* Their references are not necessarily the class name. They are just
constant (they are capitalized).
- That's why if you do CurrentGateway.name, you get
"SomeKindOfGateway" for example.
* Think of "Constantize" as Class.forName() (BUT IT'S NOT, Java
doesn't have real reflection). The name is confusing (at first I
thought it was yet another inflection, just as e.g. :dasherize).
* So, what I do is have a central configuration Ruby file (as per
convention). Being Ruby, you can reference objects (not only its
name). Loading the array with the classes themselves (instead of ,
say, their names, is useful because you get an error on initialization
if it can't find it).
- That array is accesible anywhere in the application (though I
wouldn't reference that global from a view).
* When you say SomeClass.new, you are sending the message :new (not
an operator, but just another message, just like an_array.length).
SomeClass can reference any class you like, not only a "SomeClass"
class. It's a constant. You could have used a variable...
- If you have any central class (a Base class for all your gateways
or something like that), make that know which is the current gateway
(I've called it GatewayBase, with its :current= method).
I'm sorry if I'm being confusing. I think the most important thing I
want to say is that a class reference is not coupled with a specific
implementation, it's just another constant, so it can reference to any
other. Normally we configure it statically, so we could use a Constant
name for holding the class (and then any Constant.new would do). But
if, instead of GatewayBase.current you used e.g. CurrentGateway you
could only set it once at startup (and you want that to be changes in
runtime).
Bye,
nachokb