Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
10
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

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

はじめに

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
10
Help us understand the problem. What are the problem?