Ruby on Rails Database – Using Static Lookup Tables or Constant Strings

activerecorddatabase-designruby-on-rails

In some ruby on rails projects, I have seen instances where strings are used instead of a foreign key reference to a lookup table.

I usually code in C#/SQL Server and use lookup tables, but am not particularly experienced in ruby on rails.

So my question is, should I be using strings instead of lookup tables in my ruby on rails web project (mysql and active record)? Is this something specific to ruby on rails, or to dynamically typed languages? Or for some particular circumstances? Or is it just bad database design?

By lookup tables I mean, like the following

UserStatus

Id    Name
1     Active
2     Disabled

User

Id    Username               UserStatusId
1     john.smith@gmail.com   1
1     jane.smith@gmail.com   2

Whereas with just strings

User

Id    Username               UserStatus
1     john.smith@gmail.com   active
1     jane.smith@gmail.com   disabled

Best Answer

[EDIT] Ruby on Rails 4 enums

Rails 4 supports enums, so you can declare an enum attribute where the values map to integers in the database, but can be queried by name.

class Conversation < ActiveRecord::Base
  enum status: [ :active, :archived ]
end

conversation.archived!
conversation.active? # => false
conversation.status  # => "archived"

Conversation.archived # => Relation for all archived Conversations

Conversation.statuses # => { "active" => 0, "archived" => 1 }

Rails 3 and older

You could implement something like this:

USER_STATUS_VALUES = { 1 => :active, 2 => :disabled }

class UserStatus
  attr_reader :status_id

  def status
    USER_STATUS_VALUES[@status_id]
  end

  def status=(new_value)
    @status_id = USER_STATUS_VALUES.invert[new_value]
    new_value
  end
end

You would use it like this:

my_status = UserStatus.new

my_status.status = :new
puts "status: #{my_status.status}"
puts "status_id: #{my_status.status_id}"

Will return:

status: new

status_id: 1

Note: I could have used 'active' instead of :active but in this case, use of symbols is more appropriate.

Related Topic