LegacyEnum
Allows your Rails app to interact with C-style integer-backed enumeration db columns using a more Ruby-ish syntax.
class Employee < ActiveRecord::Base
legacy_enum :payroll_type, lookup: :payroll_type_id do |e|
e.salaried 1
e.full_time 2
e.part_time 3
end
end
# You can use a symbol syntax for more readable code.
employee = Employee.new
employee.payroll_type = :salaried
# The database still sees the column as an integer
p employee.payroll_type_id
# >> 1
# Labels are provided for humanized display of your enum values
p employee.payroll_type_label
# >> Salaried
# You can still address the column as a integer field (if you have to)
employee.payroll_type_id = 3
p employee.payroll_type
# >> :part_time
Requires
- Rails >= 3.0
- Ruby >= 1.9.2
Why?
Lots of legacy apps written in C/C++/C#/Java have integer columns in the database that represent enumerated values in the system.
For example, in a legacy system dealing with employees, an employee might be classified with a C-style enumeration like:
enum PayrollType { Salaried = 1, FullTime, PartTime }
// stored in a db column named "PayrollTypeID" as its integer value
This could be accessed using legacy_enum like so:
legacy_enum :payroll_type do |e|
e.salaried 1
e.full_time 2
e.part_time 3
end
Usage
legacy_enum [rails_friendly_name], options do |e|
e.enumerated_name value, [options]
...
end
Options
Lookups
Conventionally, legacy_enum assumes that the backing int column is named the same as your field name, capitalized and postfixed with "ID". If that isn't the case, use the "lookup" option.
legacy_enum :payroll_type, lookup: :unconventional_id_column_name do |e|
...
end
Values
Legacy_enum requires that a backing value be provided for each enumerated name. A value can be an integer or a string.
legacy_enum :int_values do |e|
e.some_value 32
e.another_value 64
end
legacy_enum :string_values do |e|
e.a_string_value_is_ok 'zip_zop_zoobity_bop'
e.another_string 'here_i_go_down_the_slope'
end
Labels
Labels are automatically created and conventionally have the name [legacy_enum_field]_label. For instance, this definition would have a label named 'foo_label'
legacy_enum :foo do |e|
e.some_value 1
end
Each enumerated name, by default, has a label that is just the ActiveSupport#Titleized version of the enum name. This can be overridden using the 'label' option for each value.
legacy_enum :foo do |e|
e.crazy_label 1, label: 'Roflcopter'
end
foo = :crazy_label
p foo_label
# >> 'Roflcopter'
Scopes
ActiveRecord scopes can be created for your enumerated field, although by default they are not. The 'scope' option supports two values, :many and :one. 'Many' creates a scope with the enumeration name that accepts symbol values for the scope.
class Employee < ActiveRecord::Base
legacy_enum :payroll_type, lookup: :payroll_type_id, scope: :many do |e|
e.salaried 1
e.full_time 2
e.part_time 3
end
end
# The following scopes are created
Employee.payroll_type(:salaried)
# 'SELECT * FROM employees WHERE payroll_type_id = 1'
Employee.salaried
# 'SELECT * FROM employees WHERE payroll_type_id = 1'
Employee.full_time
# 'SELECT * FROM employees WHERE payroll_type_id = 2'
Employee.part_time
# 'SELECT * FROM employees WHERE payroll_type_id = 3'
Who?
legacy_enum was written by Sean Scally for AutoRevo with code contributed by Matt Shannon and Jordan Bach.
legacy_enum was inspired by jeffp's enumerated_attribute.
License
Released under the MIT license: