LoginSignup
7
2

More than 3 years have passed since last update.

gem enumerize の README を翻訳しました

Posted at

概要

gem enumerizeREADME を翻訳しました。

  • 翻訳について

    • 翻訳サービス DeeplGoole翻訳 の訳文を参考にしている箇所があります。
    • 翻訳対象のコミットハッシュ
    • 非公式の翻訳です。
    • 訳文がおかしい箇所があったら指摘をもらえると幸いです。
  • ライセンスについて

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

:warning: デフォルトでは、enumerize はモデルに inclusion バリデーションを追加します。skip_validations オプションを渡すことでそのバリデーションをスキップできます。:warning:

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

:warning: Mongoid で enumerize を使用している場合は、Mongoid によって定義されている名前なので、writer? をフィールド値として使用することは推奨しません。:warning:

プレフィックスの使用

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

:warning: :multiple オプションを使用したときはスコープを定義することはできません。:warning:

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.rbclass ActiveSupport::TestCase 定義内に追加することで、shoulda を使用する RSpec マッチャを使用することができます。

class ActiveSupport::TestCase
  ActiveRecord::Migration.check_pending!

  require 'enumerize/integrations/rspec'
  extend Enumerize::Integrations::RSpec

  ...
end

その他のライブラリとの統合

Enumerize は自動で下記のライブラリと統合します。

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request
7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2