LoginSignup
15
10

More than 5 years have passed since last update.

ActiveSupport::StringInquirer を使って、ステータスを active? みたいに管理する

Last updated at Posted at 2017-08-16

はじめに

Rails で User モデルに status というカラムがあるとき、

Rails.env.production?

のように

user.status.active?

と書きたいときがあります。その書き方の例です。

シンプルな実装

ActiveSupport::StringInquirer もしくは、String#inquiry メソッドを使うと簡単に実装できます。
Userモデルには string 型の status というカラムがあるものとします

app/mode/user.rb

class User < ApplicationRecord
  def status
    attribute(:status).inquiry
  end
end
[1] pry(main)> user = User.new
=> #<User:0x3ff520751674>
[2] pry(main)> user.status = :active
=> :active
[3] pry(main)> user.status.active?
=> true
[4] pry(main)> user.status = :inactive
=> :inactive
[5] pry(main)> user.status.active?
=> false
[6] pry(main)> user.status.inactive?
=> true

簡単ですね。

ちょっと凝った実装

1個のモデルの1個の属性だけにこれを適用するならば良いのですが、数が増えてくると同じようなことを何度も書く必要が出て来ます。
そんなときは、クラスマクロを実装して、シンプルに済ませませましょう。

app/mode/application_record.rb

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
  class << self
    def inquiry *attrs
      attrs.each do |attr|
        define_method attr.intern do
          attribute(attr).inquiry
        end
      end
    end
  end
end

app/mode/user.rb

class User < ApplicationRecord
  inquiry :status
end

試してみましょう。

[1] pry(main)> user = User.new
=> #<User:0x3fcca0cb0c58>
[2] pry(main)> user.status = :active
=> :active
[3] pry(main)> user.status.active?
=> true
[4] pry(main)> user.status = :inactive
=> :inactive
[5] pry(main)> user.status.active?
=> false
[6] pry(main)> user.status.inactive?
=> true

同じように動きますね。引数は複数取るようにしたので、

class User < ApplicationRecord
  inquiry :status, :gender
end

のように書くと

user.gender.female?
=> true

のようなメソッドも使えるようになります。

参考

ActiveSupport::StringInquirer
http://api.rubyonrails.org/classes/ActiveSupport/StringInquirer.html

15
10
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
15
10