Help me with my architecture - global variables in Ruby on Rails
I'm thinking about global variables in my rails application. I've searched the net about that, and found it (of course) flagged as a bad practice. I alre开发者_开发百科ady knew that.
But I have not found another way than a global variable for what I need. Can an experienced Rails programmer help me ?
What I want to do is to create a new dedicated logger, for example logging to "log/audit.txt" and share it between several controllers. Of course, I would rather not have to recreate this "logger" object for every request.
For now, I create a logger in a global variable $my_logger in an initializer, and use it across my controllers.
What do you think ? Is there a better way to do that ?
Thank you.
The general OO stance against using global variables and singletons of any type -- in Rails and in all other OO habitats -- is to avoid the "slippery slope" towards not doing OO design at all. Global variables are to be avoided as much as possible, but your logger is obviously a case where a Singleton of some sort makes sense. The Rails environment is an example: you only have on Rails environment per application, and it's essentially a Singleton. Or consider Notifier.deliver
...
Don't worry about where to put it if it must be global. Make a Singleton object with class methods as accessors and put it in lib
or anywhere you think is appropriate (making a plugin might also be appropriate, for instance). Then you just use Logger.instance.log whatever
. Of course you'll have to put in safeguards to make sure that the thing gets instantiated only once.
This SO question is extremely relevant: In Ruby on Rails how can I persist objects in memory between sessions
If you use the accepted answer, you'll be able to keep the logger in memory in production mode across requests.
However, I like the second answer... to quote:
I wouldn't worry too much about loading and discarding objects unless you can come up with a benchmark that proves it's an issue. Each request creates an extraordinary amount of intermediate objects as a matter of course, and these are generally created and destroyed in a matter of several milliseconds.
...
Benchmark first, optimize only when required.
Create your own custom logger class and require it when applicable.
Example here:
http://ianma.wordpress.com/2009/04/08/custom-logging-in-ruby-on-rails/
精彩评论