こんにちは!kossyです!
今回は、複数のフラグを1つのカラムで管理できるGem「flag_shih_tzu」の使い方とユースケースについて、
備忘録としてブログに残してみたいと思います。
環境
flag_shih_tzu とは
Booleanを含んだ配列を、一つの整数として格納できるActiveRecordのエクステンションです。MySQL, PostgreSQL、SQLite等、DBを問わず動作します。
使い方は簡単で、has_flagメソッドに、管理したいフラグ名を数値と共に渡すだけで実現できます。
ちなみに、「shih_tzu」の由来は犬の品種の一つである、「シーズー」から命名したらしいです。
使い方
まずはApplicationRecordを継承したモデルに FlagShihTzu モジュールをincludeします。
class Admin < ActiveRecord::Base include FlagShihTzu end
次に、フラグを格納するカラムを作成するマイグレーションファイルを用意します。
def change add_column :admins, :function_flags, :integer, default: 0, null: false, comment: '機能利用フラグ' end
次に、has_flagメソッドに数値と管理したいフラグ名をシンボルで渡します。
columnにカラム名を渡せば、渡したカラムでフラグを管理することができます。
class Admin < ActiveRecord::Base include FlagShihTzu has_flag( 1 => :use_announcement, 2 => :use_term_of_service_version, 3 => :use_privacy_policy, :column => 'function_flags' ) end
これで準備完了です。
各種メソッド
上記の定義を行った場合、以下のインスタンスメソッドが定義されます。
Admin#all_features # [:use_announcement, :use_term_of_service_version, :use_privacy_policy] Admin#selected_features Admin#select_all_features Admin#unselect_all_features Admin#selected_features= Admin#use_announcement Admin#use_announcement? Admin#use_announcement= Admin#not_use_announcement Admin#not_use_announcement? Admin#not_use_announcement= Admin#use_announcement_changed? Admin#has_use_announcement? Admin#use_term_of_service_version Admin#use_term_of_service_version? Admin#use_term_of_service_version= Admin#not_use_term_of_service_version Admin#not_use_term_of_service_version? Admin#not_use_term_of_service_version= Admin#use_term_of_service_version_changed? Admin#has_use_term_of_service_version? Admin#use_privacy_policy Admin#use_privacy_policy? Admin#use_privacy_policy= Admin#not_use_privacy_policy Admin#not_use_privacy_policy? Admin#not_use_privacy_policy= Admin#use_privacy_policy_changed? Admin#use_privacy_policy?
また、以下のクラスメソッドも定義されます。
Admin.use_announcement # :conditions => "(admins.function_flags in (1,3,5,7))" Admin.not_use_announcement # :conditions => "(admins.function_flags not in (1,3,5,7))" Admin.use_term_of_service_version # :conditions => "(admins.function_flags in (2,3,6,7))" Admin.not_use_term_of_service_version # :conditions => "(admins.function_flags not in (2,3,6,7))" Admin.use_privacy_policy # :conditions => "(admins.function_flags in (4,5,6,7))" Admin.not_use_privacy_policy # :conditions => "(admins.function_flags not in (4,5,6,7))"
他にも、callbackメソッドやフラグをupdateするメソッドも定義されますので、
より詳しく知りたい方はReadMeをご覧ください。
ユースケース
複数のフラグを1つのカラムで管理したくなる時がいつか?という観点で考えてみました。
1. 機能利用フラグを管理したい時
例えば管理者権限があるとして、管理者の中でも権限を弱くしたい、といったビジネス要求は往々にしてあります。
そういった際に機能ごとに使用権限を管理することになることが多いと思いますが、機能ごとにフラグのカラムを用意していくと、
機能が追加されるたびにフラグのカラムを追加することになり、管理コストが増します。
そういったケースで、このGemが役に立つのではないでしょうか。
他にもあると思うので随時更新します。
おわりに
実際に開発中のプロダクトでも、際限なく機能利用フラグが増えていっているので、すぐにでも導入したいと思いました。
既にたくさんのフラグが生えているテーブルからの移行については知見がまだないので、そういったケースでどう移行を実現するのか?は需要がありそうな気がしています。