概要
gem enumerize の README を翻訳しました。
-
翻訳について
-
ライセンスについて
- enumerize のライセンスと同様のライセンスに従います。
Enumerize
I18n と ActiveRecord/Mongoid/MongoMapper/Sequel のサポートを伴った enum 型の属性
インストール
Gemfile に下記の行を追加してください。
gem 'enumerize'
それから下記を実行してください。
$ bundle
あるいは自身で gem をインストールしてください。
$ gem install enumerize
サポートバージョン
- Ruby 2.2+
- Rails 4.2+
利用方法
基本
class User
extend Enumerize
enumerize :sex, in: [:male, :female]
end
enum 化された値はただの識別子なので、複数の単語や値を使用したい場合は、I18n
機能を使うようにしてください。
ActiveRecord:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :sex
t.string :role
t.timestamps
end
end
end
class User < ActiveRecord::Base
extend Enumerize
enumerize :sex, in: [:male, :female], default: lambda { |user| SexIdentifier.sex_for_name(user.name).to_sym }
enumerize :role, in: [:user, :admin], default: :user
end
デフォルトでは、enumerize
はモデルに inclusion
バリデーションを追加します。skip_validations
オプションを渡すことでそのバリデーションをスキップできます。
class User < ActiveRecord::Base
extend Enumerize
enumerize :sex, in: [:male, :female], skip_validations: lambda { |user| user.new_record? }
enumerize :role, in: [:user, :admin], skip_validations: true
end
Mongoid:
class User
include Mongoid::Document
extend Enumerize
field :role
enumerize :role, in: [:user, :admin], default: :user
end
MongoMapper:
class User
include MongoMapper::Document
extend Enumerize
key :role
enumerize :role, in: [:user, :admin], default: :user
end
I18n:
en:
enumerize:
user:
sex:
male: "Male"
female: "Female"
sex
属性を複数のモデルで使用する場合は、defaults
スコープを使用することができます。
en:
enumerize:
defaults:
sex:
male: "Male"
female: "Female"
i18n_scope
オプションを渡して翻訳を保管するスコープ(あるいはスコープの配列)を指定することもできます。
class Person
extend Enumerize
extend ActiveModel::Naming
enumerize :sex, in: %w[male female], i18n_scope: "sex"
enumerize :color, in: %w[black white], i18n_scope: ["various.colors", "colors"]
end
# ローカリゼーションファイル
en:
sex:
male: "Male"
female: "Female"
various:
colors:
black: "Black"
colors:
white: "White"
plain Ruby オブジェクトで I18n を使用したい場合は、ActiveModel::Naming
を extend することを忘れないようにしてください。
class User
extend Enumerize
extend ActiveModel::Naming
end
属性値の取得
@user.sex_text # or @user.sex.text
enum 化した属性のすべての値の取得
User.sex.values # or User.enumerized_attributes[:sex].values
enum 化した属性をフォームで使用する(:only
と :except
オプションをサポートしています)
<%= form_for @user do |f| %>
<%= f.select :sex, User.sex.options %>
<% end %>
ブーリアンメソッド
user.sex = :male
user.sex.male? #=> true
user.sex.female? #=> false
プリディケイトメソッド
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
Mongoid で enumerize
を使用している場合は、Mongoid によって定義されている名前なので、writer?
をフィールド値として使用することは推奨しません。
プレフィックスの使用
class User
extend Enumerize
enumerize :sex, in: %w(male female), predicates: { prefix: true }
end
user = User.new
user.sex = 'female'
user.sex_female? # => true
:only
と :except
オプションを使用してどの値にプリディケイトメソッドを作成するかを指定してください。
異なったクラス間で共有された属性を作成するためには、分離したモジュールに属性を定義して、各クラスでそれを include してください。
module PersonEnumerations
extend Enumerize
enumerize :sex, in: %w[male female]
end
class Person
include PersonEnumerations
end
class User
include PersonEnumerations
end
カスタム値(たとえば integer)で enum 属性を保存することもできます。:in
オプションを使用してハッシュを渡してください。
class User < ActiveRecord::Base
extend Enumerize
enumerize :role, in: {:user => 1, :admin => 2}
end
user = User.new
user.role = :user
user.role #=> 'user'
user.role_value #=> 1
User.role.find_value(:user).value #=> 1
User.role.find_value(:admin).value #=> 2
ActiveRecord のスコープ
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.without_sex(:male)
# SELECT "users".* FROM "users" WHERE "users"."sex" NOT IN ('male')
User.having_status(:blocked).with_sex(:male, :female)
# SELECT "users".* FROM "users" WHERE "users"."status" IN (2) AND "users"."sex" IN ('male', 'female')
Shallow スコープ
名前を付けたスコープを直接クラスに追加してください。
class User < ActiveRecord::Base
extend Enumerize
enumerize :sex, :in => [:male, :female], scope: :shallow
enumerize :status, :in => { active: 1, blocked: 2 }, scope: :shallow
end
User.male
# SELECT "users".* FROM "users" WHERE "users"."sex" = 'male'
User.active
# SELECT "users".* FROM "users" WHERE "users"."status" = 1
:multiple
オプションを使用したときはスコープを定義することはできません。
plain Ruby オブジェクトの配列ライクな属性
class User
extend Enumerize
enumerize :interests, in: [:music, :sports], multiple: true
end
user = User.new
user.interests << :music
user.interests << :sports
ActiveRecordの場合
class User < ActiveRecord::Base
extend Enumerize
serialize :interests, Array
enumerize :interests, in: [:music, :sports], multiple: true
end
すべてのテキスト値の配列を取得
@user.interests.texts # shortcut for @user.interests.map(&:text)
また、super
メソッドを使用して enum 属性値を参照することでリーダーメソッドをオーバーライドすることもできます。
def sex
if current_user.admin?
"Super#{super}"
else
super
end
end
SimpleForm
SimpleForm gem を使用している場合は、input タイプ(デフォルトで:select
になります)とコレクションを指定する必要はありません。
<%= simple_form_for @user do |f| %>
<%= f.input :sex %>
<% end %>
ラジオボタンを設定したい場合
<%= simple_form_for @user do |f| %>
<%= f.input :sex, :as => :radio_buttons %>
<% end %>
Enumerize は SimpleForm の I18n キーを上書きすることに注意してください。enum 属性に関わる input においては SimpleForm のキーの代わりに enum キーが使用されます。これを避けたい場合は、input
の呼び出しに :collection
オプションを渡してください。
Formtastic
Formtastic gem を使用している場合は、input タイプ(デフォルトで:select
になります)とコレクションを指定する必要はありません。
<%= semantic_form_for @user do |f| %>
<%= f.input :sex %>
<% end %>
ラジオボタンを設定したい場合
<%= semantic_form_for @user do |f| %>
<%= f.input :sex, :as => :radio %>
<% end %>
RSpec
組み込みの Rspec マッチャを使用することもできます。
class User
extend Enumerize
enumerize :sex, in: [:male, :female]
end
describe User do
it { should enumerize(:sex) }
# RSpec3 のシンタックス
it { is_expected.to enumerize(:sex) }
end
修飾子
in
:in
オプションの利用をテストするために in
修飾子を使用してください。
class User
extend Enumerize
enumerize :sex, in: [:male, :female]
end
describe User do
it { should enumerize(:sex).in(:male, :female) }
end
in
修飾子を利用することでカスタム値を持つ enum 属性値をテストすることができます。
class User
extend Enumerize
enumerize :sex, in: { male: 0, female: 1 }
end
describe User do
it { should enumerize(:sex).in(male: 0, female: 1) }
end
with_default
with_default
オプションの利用をテストするために with_default
修飾子を使用してください。
class User
extend Enumerize
enumerize :sex, in: [:male, :female], default: :female
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_default(:female) }
end
with_i18n_scope
with_i18n_scope
オプションの利用をテストするために with_i18n_scope
修飾子を使用してください。
class User
extend Enumerize
enumerize :sex, in: [:male, :female], i18n_scope: 'sex'
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_i18n_scope('sex') }
end
with_predicates
with_predicates
オプションの利用をテストするために with_predicates
修飾子を使用してください。
class User
extend Enumerize
enumerize :sex, in: [:male, :female], predicates: true
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_predicates(true) }
end
with_predicates
修飾子を使用することでプレフィックスのある predicate をテストすることができます。
class User
extend Enumerize
enumerize :sex, in: [:male, :female], predicates: { prefix: true }
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_predicates(prefix: true) }
end
with_scope
:scope
オプションの利用をテストするために with_scope
修飾子を使用してください。
class User
extend Enumerize
enumerize :sex, in: [:male, :female], scope: true
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_scope(true) }
end
with_scope
修飾子を使用することでカスタム scope をテストすることができます。
class User
extend Enumerize
enumerize :sex, in: [:male, :female], scope: :having_sex
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_scope(scope: :having_sex) }
end
with_multiple
:multiple
オプションの利用をテストするために with_multiple
修飾子を使用してください。
class User
extend Enumerize
enumerize :sex, in: [:male, :female], multiple: true
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_multiple(true) }
end
Shoulda を使用する Minitest
下記の2行を test_helper.rb
の class ActiveSupport::TestCase
定義内に追加することで、shoulda を使用する RSpec マッチャを使用することができます。
class ActiveSupport::TestCase
ActiveRecord::Migration.check_pending!
require 'enumerize/integrations/rspec'
extend Enumerize::Integrations::RSpec
...
end
その他のライブラリとの統合
Enumerize は自動で下記のライブラリと統合します。
Contributing
- 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