views:

190

answers:

4

Hello,

I'm thinking about a social networking-site. My user-model should have an attribute "eyecolor", which could be set on a view-page with a select-box/dropdownlist.

My question: -> should I make a AR-Model or should I use a global Hash/Constant for the data? Is there a best practice for "static-models"?

And how do I associate following without an AR-Model with relations:

u = User.first 
u.eyecolor 
==> 1 (not the eyecolor-string!)

What I need is the eyecolor-string:

u = User.first 
u.eyecolor 
==> "brown"

Thanks, sorry for my bad english!

+6  A: 

You could create a model to handle your eye-color logic:

class EyeColor
   COLORS = ['blue','brown','hazel']

   attr_accessor :color

   # Some logic methods...
   def is_brown?
     self.color == 'brown'
   end

end

Note: this model is not an Active Record model, but it does create an abstraction the real-world object you are trying to model.

EDIT: I also like this approach as opposed to a global hash, because it gives it organizes your static definition within EyeColor instead of floating around in your program, which makes it clear where this definition is.

<%= select :user, :eye_color, EyeColor::COLORS %>

EDIT: added question mark to predicate method.

berlin.ab
The other nice thing about this particular approach is you get an opportunity to move on if you find the abstraction becomes greater than a simple lookup. Essentially the refactor becomes a matter of adding a couple of methods or making the class inherit from AR.
robertpostill
I really like this idea but am having trouble coming up with code that works for me. In my site I want to allow the admin to change the name of the site (SITE_NAME) and store it in the DB. However, I think its overkill to retrieve SITE_NAME every time I need to display a page. Could you give a bit more detail on the "Some logic methods..." section of your answer? :)Thanx! Richard
RNHurt
http://pastie.org/482993I've mocked up some code here. Does this look workable or am I traveling down the wrong road?
RNHurt
+5  A: 

What you want is a Constant. I put these in a file in config/initializers/constants.rb; that way they are all in the same place.

EyeColors = %w{Blue Brown Hazel Green}

In your form just do:

<%= f.select :eye_color, EyeColors %>
Matt Darby
A: 

You might want to check into constant_cache. Storing this info in the DB, but having it cached lets you add/remove constants (in the db) without changing your actual code.

Bill
+2  A: 

If you have some data, you should put it in the database. This doesn't mean you have to load it each time you use it:

class EyeColor < ActiveRecord::Base
  has_many :users

  def self.allowed_eye_colors
    @@eye_colors ||= AllowedEyeColor.find(:all)
  end
end

You access this as EyeColor.allowed_eye_colors. It's loaded the first time you use it, and then cached in the class variable.

Sarah Mei
Gave an up-vote for this a year later. I like it better than my own answer.
berlin.ab