2

New to rails so not sure what the best approach is here. I want to define a simple c++ style enum which can then be used as a custom type in my db. The enum can be simulated with an array or a custom module but how do I go about turning that into a custom type for my table?

3 Answers 3

6

Here's a pattern I follow in rails:

In my model class, I add a module to hold the possible values of the column. Then I put them into an array and define validation against the array of possible values.

Imagine I have a column/attribute called status and it can be three possible values. I'd do this:

class MyModel < ActiveRecord::Base

  # This validates that status can't be null
  validates :status, :presence => true  

  # Define a module with all possible values
  module Status
    IN_DEVELOPMENT = 'in development'
    DISABLED = 'disabled'
    ACTIVE  = 'active'
  end

  # Now create an array of possible status values, and add a validation
  STATUSES = [ Status::DISABLED, Status::ACTIVE, Status::IN_DEVELOPMENT]
  validates :status, :inclusion => { :in => STATUSES, :message => "%{value} is not a valid status value" }

end
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Kevin, I tried something similar before but migration doesn't recognize the array definition as a custom type. I get an error saying # Could not dump table "hostprofiles" because of following StandardError # Unknown type 'SERVICES' for column 'service'
In general I've found it best to suspend past practices and try to 'go the rails way' in situations like this. Inevitably, things go faster and are smoother. Why are custom types so important? Can you use the types that come with rails?
@KevinBedell can you explain the use or need for that module, rather than just giving an array of values? I'm just curious.
1

Have you considered using the built-in enumeration support in your database? Lots of common RDMBSes have enum support, such as Postgres (see http://www.postgresql.org/docs/9.1/static/datatype-enum.html) and MySQL (see http://dev.mysql.com/doc/refman/5.5/en/enum.html). With that, you can directly create the type in your data store and then use it via one of the ActiveRecord plugins (such as enum_type for Postgres: https://github.com/riscfuture/enum_type).

Alternatively, you could use something like active_enum to structure the enumeration as you described and store fields as integers in the database.

1 Comment

I actually didn't know that. Thanks for the links, I'll look into it.
1

Depending on how you plan to utilize this enum type in your code I've found that using scopes accomplishes close to the same thing along with an enum type in the database to ensure only specific values are set.

Example:

scope :trial, :conditions => { :utype => 'TRIAL' }
scope :registered, :conditions => { :utype => 'REGISTERED' }
scope :active, :conditions => { :status => 'ACTIVE' }
scope :abuse, :conditions => { :status => 'ABUSE' }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.