Enumerated attributes with I18n and ActiveRecord/Mongoid support
Add this line to your application's Gemfile:
gem 'enumerize'
And then execute:
$ bundle
Or install it yourself as:
$ gem install enumerize
Basic:
class User
extend Enumerize
enumerize :sex, in: [:male, :female]
end
ActiveRecord:
class User < ActiveRecord::Base
extend Enumerize
enumerize :sex, in: [:male, :female]
enumerize :role, in: [:user, :admin], default: :user
end
Mongoid:
class User
include Mongoid::Document
extend Enumerize
field :role
enumerize :role, in: [:user, :admin], default: :user
end
I18n:
en:
enumerize:
user:
sex:
male: "Male"
female: "Female"
or if you use sex
attribute across several models you can use this:
en:
enumerize:
sex:
male: "Male"
female: "Female"
get attribute value:
@user.sex_text # or @user.sex.text
get all values for enumerized attribute:
User.sex.values # or User.enumerized_attributes[:sex].values
use it with forms:
<%= form_for @user do |f| %>
<%= f.select :sex, User.sex.options %>
<% end %>
Boolean methods:
user.sex = :male
user.sex.male? #=> true
user.sex.female? #=> false
Predicate methods:
class User
extend Enumerize
enumerize :sex, in: %w(male female), predicates: true
end
user = User.new
user.male? # => false
user.female? # => false
user.sex = 'male'
user.male? # => true
user.female? # => false
Using prefix:
class User
extend Enumerize
enumerize :sex, in: %w(male female), predicates: { prefix: true }
end
user = User.new
user.sex = 'female'
user.sex_female? # => true
Use :only
and :except
options to specify what values create predicate methods for.
To make some attributes shared across different classes it's possible to define them in a separate module and then include it into classes:
module PersonEnumerations
extend Enumerize
enumerize :sex, in: %w[male female]
end
class Person
include PersonEnumerations
end
class User
include PersonEnumerations
end
It's also possible to store enumerized attribute value using custom values (e.g. integers). You can pass a hash as :in
option to achieve this:
class User < ActiveRecord::Base
extend Enumerize
enumerize :role, in: {:user => 1, :admin => 2}
end
ActiveRecord scopes:
class User < ActiveRecord::Base
extend Enumerize
enumerize :sex, :in => [:male, :female], scope: true
enumerize :status, :in => { active: 1, blocked: 2 }, scope: :having_status
end
User.with_sex(:female)
# SELECT "users".* FROM "users" WHERE "users"."sex" IN ('female')
User.having_status(:blocked).with_sex(:male, :female)
# SELECT "users".* FROM "users" WHERE "users"."status" IN (2) AND "users"."sex" IN ('male', 'female')
Array-like attributes with plain ruby objects:
class User
extend Enumerize
enumerize :interests, in: [:music, :sports], multiple: true
end
user = User.new
user.interests << :music
user.interests << :sports
and with ActiveRecord:
class User < ActiveRecord::Base
extend Enumerize
serialize :interests, Array
enumerize :interests, in: [:music, :sports], multiple: true
end
If you are using SimpleForm gem you don't need to specify input type (:select
by default) and collection:
<%= simple_form_for @user do |f| %>
<%= f.input :sex %>
<% end %>
and if you want it as radio buttons:
<%= simple_form_for @user do |f| %>
<%= f.input :sex, :as => :radio_buttons %>
<% end %>
If you are using Formtastic gem you also don't need to specify input type (:select
by default) and collection:
<%= semantic_form_for @user do |f| %>
<%= f.input :sex %>
<% end %>
and if you want it as radio buttons:
<%= semantic_form_for @user do |f| %>
<%= f.input :sex, :as => :radio %>
<% end %>
Enumerize integrates with the following automatically:
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Added some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request