Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

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

norifumi
Rubyが好きですが、他の言語も嫌いでは無いです。
poke-m
ポケットマルシェ(ポケマル)は、全国の生産者と消費者を直接繋ぐCtoCプラットフォームです。
https://poke-m.com/
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした