enum_field
Enables Active Record attributes to point to enum like objects, by saving in your database only an integer ID.
Install
gem 'galetahub-enum_field', require: 'enum_field'
Features
- Allows creation of Classes with enum like behaviour.
- Allows any number of members and methods in the enum classes.
- Allows an integer id to be used in your database columns to link to the enum members (user.role_id)
- Enables higher abstraction interaction with +AR+ attributes:
user.role = Role.admin
if user.role.can_edit?
- Saves in your +AR+ tables, only an integer id pointing to the enumeration member.
Synopsis
When in an Active Record class, you have an attribute like role, state or country you have several options.
- You can create a roles, states or countries table, and dump there all possible values.
- You can use a string to identify, for instance, the role.
- You can use an id to identify the role.
If you are not comfortable with any of this options, maybe +enum_field+ is an answer for you.
Basic usage
Define rules:
class Role
include EnumField::DefineEnum
define_enum do
member :admin
member :manager
member :employee
end
end
class User < ActiveRecord::Base
extend EnumField::EnumeratedAttribute
# in the database table there is a role_id integer column
enumerated_attribute :role
end
Usage:
user.role = Role.manager
user.role_id == Role.manager.id # will be true
Role.manager.name # :manager
user.role.name # :manager
Role.names # [:admin, :manager, :employee]
Role.ids # [1, 2, 3]
User.first.role.id == User.first.role_id # will be true
Role[:manager] == Role.manager # will be true
Role['manager'] == Role.manager # will be true
instance = Role[:employee]
instance.admin? # false
instance.employee? # true
Your enum classes can have all the methods you need:
class PhoneType
include EnumField::DefineEnum
attr_reader :prefix
def initialize(prefix)
@prefix = prefix
end
define_enum do
member :home, object: new('045')
member :commercial, object: new('044')
member :mobile, object: new('+380')
end
end
user.phone_type.prefix # +380
user.phone_type.name # :mobile
You have some +AR+ like methods in enum classes
PhoneType.all == [PhoneType.home, PhoneType.commercial, PhoneType.mobile] # ordered all
PhoneType.first == PhoneType.home
PhoneType.last == PhoneType.mobile
PhoneType.find_by_id(PhoneType.home.id) == PhoneType.home
PhoneType.find_by_id(123456) == nil # will not raise if id does not exists
PhoneType.safe_find(123456) == nil # just alias for find_by_id
PhoneType.find(2) == PhoneType.commercial
PhoneType.find(123456) # will raise
PhoneType.find([1, 2]) == [PhoneType.home, PhoneType.commercial]
Start id from specific number
class CommentType
include EnumField::DefineEnum
define_enum id_start_from: 100 do
member :video
member :audio
member :text
end
end
CommentType.video.id # 101
CommentType.audio.id # 102
CommentType.text.id # 103
Check if id exists
CommentType.valid_id?(-1) # false
CommentType.valid_id?(0) # false
CommentType.valid_id?(nil) # false
CommentType.valid_id?(1) # false
CommentType.valid_id?('101') # false
CommentType.valid_id?(:text) # false
CommentType.valid_id?(101) # true
Check if name exists
CommentType.valid_name?('video') # true
CommentType.valid_name?(:video) # true
CommentType.valid_name?(nil) # false
CommentType.valid_name?(1) # false
CommentType.valid_name?('wrong') # false
CommentType.valid_name?(:wrong) # false
Tests
bundle install
bundle exec rspec ./spec/
LICENSE
(The MIT License)
Copyright (c) 2017 Fodojo LLC