動かざることバグの如し

近づきたいよ 君の理想に

Rails開発をもっと楽しくする便利メソッド集

この記事はRuby on Rails Advent Calendar 2018の7日目です。

はじめに

今回は知らなくても生きていけるけど、知っておいたほうがお得で便利なRailsメソッドを紹介していく。RailsといいつつActiveSupportやんけ

squish

冒頭と末尾のホワイトスペースを削除して、連続したホワイトスペースを1つだけになるように整形してくれる。

" hoge \n \t piyo   fuga\n".squish
=> "hoge piyo fuga"

try

知ってる人は常識だけど未だに知らない人多い。例えば以下のようにpostに紐づくuserのlogin.idを有れば取得する場合、

post = Post.last
post.user.present? && post.user.login.present? && post.user.login.id

以下のように短くできる。

post = Post.last
post.try(:user).try(:login).try(:id)

presence

便利なのに、present? に比べて presence知名度が低い印象。

nilかどうかチェックしてnilならAを、違うならそのまま返したいときに

object.present? ? object : 'nanasi'

と書くところを簡単にできる。ぜひ使ってほしい。

name.presence || 'nanasi'

presence_in

これも present? に比べて知名度低い。引数のリスト中にあればそれ自身を返す。なければnil いわゆるホワイトリストに使える。

'admin'.presence_in %w(admin staff viewer)
=> "admin"
'invalid'.presence_in %w(admin staff viewer)
=> nil

all_week, all_month, all_year

例えば今月の初日から末尾までをrangeで欲しい場合、普通に書くと

Date.today.beginning_of_month..Date.today.end_of_month

となるが、all_month で一発

Date.today.all_month
=> Sat, 01 Dec 2018..Mon, 31 Dec 2018

とできる。 他にも all_year も便利。

Date.today.all_week
=> Mon, 03 Dec 2018..Sun, 09 Dec 2018
Date.today.all_year
=> Mon, 01 Jan 2018..Mon, 31 Dec 2018
Date.today.all_year.count
=> 365 # 当然w

all_day

all_day はその日まるごとの時間をrangeで取得できる。

Date.today.all_day
=> Wed, 05 Dec 2018 00:00:00 JST +09:00..Wed, 05 Dec 2018 23:59:59 JST +09:00

to_s(:db)

さっきの all_*** と組み合わせると強い。

(Date.today..Date.tomorrow).to_s(:db)
=> "BETWEEN '2018-12-05' AND '2018-12-06'"

overlaps?

2つのrangeに対して、重複している部分があるかをチェックする。

(1..10).overlaps?(3..6)
=> true
(1..10).overlaps?(11..20)
=> false

rangeに対して使えるので、日付とかでもOK。

(Date.new(2018,12,1)..Date.new(2018,12,10)).overlaps?(Date.new(2018,12,3)..Date.new(2018,12,6))
=> true