views:

932

answers:

5

I have a state field that stores the value as 2 characters. For example, Alabama is saved as AL, Alaska is saved as AK, Arizona is saved as AZ, etc. In the show.html.erb, how do I display the long name for the state such as Alabama instead of just showing AL? Is this possible or should I just store the long name in the database such as Alabama, Alaska, Arizona, etc?

+5  A: 

Write a method that would output long name of a stateand call it in show.html.erb

some_model.rb:

SomeModel < ActiveRecord::Base
  STATE_CODES = {
    "AL": "Alabama", "AK": "Alaska",
    # add remaining 50
  }
  def state_human_name
    STATE_CODES[self.state]
  end

show.html.erb:

<%= record.state_human_name %>

EDIT: It does not help to store full names of states in your database -- you'll need short forms at least somewhere and therefore would need to add mapping between short and long forms anyway.

Alex Lebedev
I was storing the STATE_CODES as "Alabama" => "AL" instead of "AL" => "Alabama" If I do it your way, the option value in my form field would appear as <option value="Alabama">AL</option>. How do I make it show up as <option value="AL">Alabama</option> instead? What would the select tag look like?
select("your_object", "state", SomeModel::STATE_CODES.collect { |code, name| [name, code] })
cpm
+1  A: 

Is there a reason for using the 2 letter codes (e.g. a legacy database)? If not I would stick to the usual ActiveRecord idiom and have a separate "states" table linked by id. If you need the 2 letter code for display purposes, printing address labels or whatever then add add a 'state_code' attribute to the states table but don't use it as a primary key.

Noel Walters
There's nothing un-idiomatic about having a hash lookup table in the model in this case! :) Unless if I wanted users to be able to update the states, I would prefer Alex's approach since the states change so infrequently. Removes one more thing that can go wrong when setting up a new installation.
cpm
Point taken! if the data doesn't change then why keep it in a database? but it goes against my instincts to have the whole list permanently occupying memory, and I wouldn't trust the assumption that I'd never need to attach other attributes to states (population, postage charges or whatever)
Noel Walters
If you ever think you might need international addressing, you should put it in the database.
Sarah Mei
A: 

In response to the comment "I was storing the STATE_CODES as "Alabama" => "AL" instead of "AL" => "Alabama" If I do it your way, the option value in my form field would appear as AL. How do I make it show up as Alabama instead? What would the select tag look like? – Max (12 hours ago)"

When passing STATE_CODES to the options method or select method, use STATE_CODES.invert, which switches keys and values.

Tilendor
Nice! Never knew about Hash#invert. Thanks ;)
Matt Darby
A: 

Tilendor, I notice that if I use STATE_CODES.invert, the drop-down menu selection would get out of order. For example, the first five lines of my option list is shown below:

New Hampshire Ohio Colorado Minnesota Alabama ...

In my STATES_CODES hash, I have the following listed in the order below:

"AL" => "Alabama", "AK" => "Alaska", "AZ" => "Arizona", "AR" => "Arkansas", "CA" => "California", ...

Is there a way to have the options listed in the form in the same order as the STATES_CODES? Maybe sort them alphabetically?

Max
A: 

I put this in a comment, but I've decided it's sufficiently different that it warrants an answer.

When you're deciding where to keep your state map, consider whether you'll ever need to ship things to Canada, or further afield. If so, it's worth the effort to set up a states table, linked to a countries table.

And anyway, if your data rarely changes, it's less issue-prone to put it in the database, because code changes far more often. More frequent changes = more opportunities to mess it up. Plus, it's then trivial to sort as you like.

class State < ActiveRecord::Base
  def self.get_states
    @@states || State.find(:all, 
                           :include => :country, 
                           :order => 'countries.name, long_name')
  end
end
Sarah Mei