views:

3974

answers:

5

I have some data that I want to store somewhere in my Rails app because I use it for generating form fields, checking a submitted form to ensure its values are valid, etc. Basically, I want the data in one location because I make use of it in several places.

Previously, I was defining an initialize method in my controller and initializing instance variables within that method, e.g. @graph_types = ['bar', 'line']. This seemed a bad idea because that's really all initialize was being used for (initializing those values) and the instance variables could be changed later, which I don't want.

Now, I define constants outside of any method in my controller, right up at the top after my filters, and I freeze them, e.g. GraphTypes = ['bar', 'line'].freeze.

I didn't want to store such data in a config file because then I would have to keep track of an extra file, read in the file and parse it, etc. I didn't want to store this data in the database because that seems like overkill; I don't need to do any crazy LEFT OUTER JOIN-type queries combining available graph types with another of my constants, say Themes = ['Keynote', 'Odeo', '37 Signals', 'Rails Keynote'].freeze. I didn't want to store the data in environment.rb because this data only pertains to a particular controller.

Considering all this, am I going about this 'the Ruby way'?

+3  A: 

I believe what you are currently doing is fine; you said the data only pertains to one controller, and therefore that's where it belongs. If it was needed for multiple controllers, or if they were more complex than constant values, other approaches may make sense.

J Cooper
+3  A: 

Yes, what you are doing is fine. It's more idiomatic Ruby to call your contant GRAPH_TYPES though.

Incidentally, I would avoid defining initialize in your controllers. Seems like it could lead to trouble.

Daniel Lucraft
+1  A: 

If you are generating forms that are related to some resource then it will be good variant to store it in the models. You don't need to store it in DB because it can be simple class or instance variables/methods.

The same idea is for validation. If you are validating resources/model instances then it will be reasonable choice to store validation parameters inside model class.

Anyways, it will be much closer to the 'thick model and thin controller' pattern then any of the variants you mentioned.

IDBD
+4  A: 

For constants that don't really belong anywhere else I have a StaticData class.

  class StaticData

    GRAPH_TYPES = ['bar', 'line']

    SOMETHING_ELSE = ['A', 'B']

  end

Then I get at it with

StaticData::GRAPH_TYPES
Where do you put the class? Do you locate it in with your models?
ahsteele
Well, I do put it in the models directory, but it would probably be better to put it in lib.
+2  A: 

I would agree some what with IDBD and paradisepete. Using constants in the model would be the best way to go so that the controller is skinny and the model fat. see Rails view tips For example if you had a metrics controller linked to a metric model. In the metric model class Metric < ActiveRecord::Base GRAPHTYPES = ['bar', 'line']

Then in the view you could do something like

f.select :graph_type, Metric::GRAPHTYPES