Active Support一時調べ
Active Supportとは
Active SupportはRuby on Railsのコンポーネントであり、Ruby言語の拡張、ユーティリティ、その他横断的な作業を担っています。
Active Supportは言語レベルで基本部分を底上げして豊かなものにし、Railsアプリケーションの開発とRuby on Railsそれ自体の開発に役立てるべく作られています。 (引用:Active Support コア拡張機能) https://railsguides.jp/active_support_core_extensions.html
StringやInteger、Date、Datetimeなどのコアなクラスのメソッドを拡張してくれるもの
拡張対象
Active Supportが拡張する対象を ざっと挙げてみました(全部ではないです)
- Object
- Module
- Class
- String
- Numeric
- BigDecimal
- Integer
- Enumerable
- Array
- Hash
- Range
- Date
- Time
- File
- NameError
- LoadError
...
全てのオブジェクトで使える拡張
- Object#blank?
- Object#present?
rubyにあるのはnil?
とempty?
のみ
nil.nil? => true [].empty? => true ''.empty? => true
- Object#blank?
nil?
とempty?
の合わせ技
nil.blank? => true [].blank? => true ''.blank? => true nil.blank? => true
- Object#present?
!blank?
と同じ意味
nil.present? => false [].present? => false [1,2,3].present? => true
blank?とpresent?の定義は下のURL先 https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/blank.rb
- Object#try
おなじみtryメソッド。 レシーバがnil、もしくはメソッドが定義されていない時にはnilを返す。nilでないなら引数で渡されたメソッドを実行。
"test".try(:name) => nil "test".try(:size) => 4
- Object#try!
try
と違う点は、レシーバがnilならnil
でなく例外を返すところ。
"test".try!(:name) NoMethodError: undefined method `name' for "test":String # NoMethodErrorクラスの例外が発生
- Object#with_options
オプションを一つにまとめられる。
validates
メソッドのオプションを一つにまとめたりとかもできると思うよ。
class Company < ApplicationRecord ... has_many :contracts, dependent: :destroy has_one :billing_address, dependent: :destroy has_many :billings, dependent: :destroy ... end ↓ class Company < ApplicationRecord ... with_options dependent: :destroy to |comp| comp.has_many :contracts comp.has_one :billing_address comp.has_many :billings ... end
- tapの補足
ブロックを渡した場合には、nilでない場合のみブロックの評価を行い、tryの返り値はブロックの評価結果となる。
array => [["test1", 1], ["test2", 2]] array.try do |a| a.to_h end => {"test1"=>1, "test2"=>2} array.try do |a| a.to_h end.values => [1, 2] # Object#yield_selfも同様の挙動 array.yield_self do |a| a.to_h end.values => [1, 2]
Classの拡張
class_attribute
継承可能なクラス属性を定義する。 以下のようなことができるようになる。
- 子クラスで上書きが可能
- アクセサメソッドを自動で定義
- 子クラスで定義されていなければ親クラスの値を参照
親クラスの定数を汚染する恐れがない。インスタンスメソッド内からでもアクセスできる。
class A class_attribute :x end class B < A; end class C < B; end A.x = :a B.x # => :a C.x # => :a B.x = :b A.x # => :a C.x # => :b C.x = :c A.x # => :a B.x # => :b # インスタンスからもアクセス・書き換え可能 # インスタンスからクラスのclass_attributeを書き換えることはない test = B.new test.x = :t test.x # => :t B.x = :b
Stringの拡張
- 活用系
レシーバに対して何かしら操作を行う系
"tomato".pluralize => "tomatoes" "katsui".pluralize => "katsuis"
活用系の続き
"admin_user".camelize => "AdminUser" "admin_user".camelize(:lower) => "adminUser" "account/financial_account".camelize => "Account::FinancialAccount" # camelizeと反対の操作を行うのがunderscore "Backoffice::UsersController".demodulize => "UsersController" "::UsersController".demodulize => "UsersController"
Numericの拡張
- バイト
全ての数値が以下のメソッドに対応している。
bytes kilobytes megabytes gigabytes terabytes petabytes exabytes
2.bytes => 2 2.kilobytes => 2048 2.megabytes => 2097152
- 書式設定
指定した形式で数値をフォーマットできる
# 電話番号 1234567.to_s(:phone) => "123-4567" 1234567891.to_s(:phone) => "123-456-7891" 1234567891.to_s(:phone, area_code: true) => "(123) 456-7891" // 桁区切り 12345678.to_s(:delimited) => "12,345,678" pry(main)> 12345678.to_s(:delimited, delimiter: ".") => "12.345.678" // 丸める 111.2345.to_s(:rounded) => "111.235" 111.2345.to_s(:rounded, precision: 2) => "111.23" 1112903.to_s(:rounded, precision: 3) => "1112903.000"
Enumerableの拡張
# sum # 要素の合計値を返す # 数値でない場合は+を使ってsumを計算する [2,3,4].sum => 9 (1..10).sum => 55 %w(rb yml haml).sum => "rbymlhaml" # many? # collection.size > 1 の短縮系 [1,2,3,4].many? => true # many?ではブロックの評価も行える # ブロックの場合、評価結果のcollection > 1かどうか判定する [1,2,3,4].many? { |a| a % 2 == 0 } => true [1,2,3,4].many? { |a| a % 3 == 0 } => false # pluck # 指定したkeyに基づく配列を返す [ { id: 1 }, { id: 2 }, { id: 3 } ].pluck(:id) => [1, 2, 3]
Hashの拡張
# deep_merge # レシーバと引数に同じkeyが存在し、かつ値がHashの時に下位のHashをmergeする {a: {b: 1}}.deep_merge({a: {c: 2}}) => {:a=>{:b=>1, :c=>2}} # exceptとexcept! # 引数で指定したkeyがあればレシーバのHashから取り除く {a: 1, b: 2}.except(:a) => {:b=>2} # stringify_keysとsymbolize_keys # レシーバのHashのkeyをシンボル→文字列に変換(stringify_keys) # レシーバのHashのkeyを文字列→シンボルに変換(symbolize_keys) {nil => nil, 1 => 1, a: :a}.stringify_keys => {""=>nil, "1"=>1, "a"=>:a} {nil => nil, 1 => 1, "a" => "a"}.symbolize_keys => {nil=>nil, 1=>1, :a=>"a"}
まとめ
あなたが実装しようとしているメソッドは、既にActive Supportが提供しているかもしれないので、一旦落ち着いて探しましょう
比較的Active Supportのドキュメントは読みやすく、発見も色々とあるので読んでみるといいよ!