Railsのバージョンは3.2.8時点のものです。(2012/8/21追記)
前回の冒頭で書いてたので、Rails版も書いてみようと思う。
要は、困ったらリファレンスマニュアルのそれっぽいところ見れば、
Ruby/Railsは大体解決してくれるよ(しかもスマートに)って感じなので、
悩んだらハマる前に一回公式に帰るのもいい手段だと思ってます。
でも、RailsのAPIリファレンスどこに何書いてるか分かりづらいと思う。
例えば、has_many関連には、実は:after_addとか:before_removeとか、
その手のコールバックをProcで渡せるんだけど、メソッドの説明の所に書いてないんよね。
上の方のクラス全体の説明の所にAssociation Callbackって項目があって、
そこで地味に説明されてたりとか。
この辺、もしかしてpull request候補かな。
メインはActiveSupportです。
細かいところまで書くとキリが無いので、単純にメソッドとして解説できるものだけ。
Rails3レシピブック等で、あまり記述が無かったり
書いてあるけど忘れがちと思ってる所を挙げてます。
同じく突っ込み歓迎。
ActionView
#video_tag(sources, options = {})
配列でファイル名を渡すと、展開して複数ソースを持ったvideoタグに展開してくれる。
audio_tagとか、favicon_link_tagとかもあったりする。
#number_with_delimiter(number, options={})
123456を123,456って感じで表示してくれる。
区切り文字はオプションで変えられる。
#highlight(text, phrases, *args)
textの中でphrasesに合致するものがあれば、ハイライト表示するためのタグで囲んでくれる。
見せ方はcssで調整。
どのタグで包むかは、highlihgerオプションで調整できる。
ActiveRecord
ActiveRecord::Persistence#toggle(attribute)
Booleanな属性名を渡すと、trueとfalseを入れ替えてくれる。
ActiveRecord::Store.store
DBにHashをシリアライズしてデータを保存し、直接データにアクセスできるアクセサメソッドを定義してくれる。
ただシリアライズして欲しいだけなら、serializeメソッドが使える。
class User < ActiveRecord::Base store :settings, accessors: [ :color, :homepage ] end u = User.new(color: 'black', homepage: '37signals.com') u.color # Accessor stored attribute u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
ActiveRecord::Relation#first_or_create(attributes = nil, options = {}, &block)
そのクラスのテーブルの最初の要素があればそれを利用し、
無ければattributesを使ってレコードを作成し、それを返す。
スコープと組み合わせたり、ブロックを渡す使い方が便利。
User.where(:first_name => 'Scarlett').first_or_create do |user| user.last_name = "O'Hara" end
ActiveRecord::Relation#to_sql
スコープを使って戻ってきたRelationオブジェクトで実行する。
どういうSQLが帰ってくるかすぐに確認できるので、デバッグに便利。
ActiveSupport
ActiveSupport::Concern#included(base = nil, &block)
自分が何かモジュールを書く時に、includeされたら、呼出側のクラスのコンテキストで実行される処理を
ブロックで記述できる。
ActiveSupport::Concernはモジュール書く時に非常に便利なので、
リファレンスマニュアルを読んでおくことをオススメしたい。
module Activatable included do scope :active, lambda {where(:activate => true)} end end
ActiveSupport::StringInquirer
厳密にはメソッドじゃないけど、method_missingを使って、問い合わせメソッド的に処理してくれる。
実は、こんな感じで書ける。
String#inquiryで、普通の文字列から変換できる。
Rails.env.production? # Rails.env == "production" と同じ
ActiveSupportのコア拡張
Array#from(position)
positionで指定したインデックスから配列の最後までを取る。
Array[2..-1]と書くより直感的。
Hash#assert_valid_keys(*valid_keys)
引数で渡したkey以外が含まれていると例外を起こす。
オプションとして受けとったHashの値を検証して、
メソッドのガード条件として使う。
Hash#with_indifferent_access
HashをHashWithIndiferrentAccessに変換する。
Railsではシンボルアクセスが多いので、たまに普通のHashだと
データ取り損ねたりするので、防御的に変換かけたりすることがある。
Module.delegate
Delegatorパターンを簡単に書ける。
Ruby組み込みのDelegatable, Fowardableより楽。
prefixオプションを渡してメソッド名を調節したり、
allow_nilオプションで移譲先が無い場合はnilを返すようにしたり。
class Foo < ActiveRecord::Base belongs_to :greeter delegate :hello, :goodbye, :to => :greeter end Foo.new.goodbye # => "goodbye"
Object#to_s(format = :default)
to_sに引数渡せるようになっていて、
:dbを渡すと、DBクエリとして活用する時の文字列表現が取れる。
Object#present?
Object#blank?の逆。
文字列だったら、空文字列じゃない場合にtrueになる。
nilに対しても呼べるので条件式書く時に楽。
Object#presence
a = hoge.presence
# -> a = hoge.present? ? hoge : nil
Object#try(method_name, args, &block)
既に定番かな。メソッドチェインのどっかでnilになったら、
後全部nilで評価してくれるので、NoMethodErrorにならない。
複数引数も渡せるし、ブロックも渡せる。
最後に || と組み合わせてtryでnilになったら、そっちを返すようにするなど。
first_post_title = user.posts.first.try(:title) || "No Post"
Range#overlaps?(other)
Range同士が被っている場所が無いか比較してくれる。
String#to_time, #to_date
テストコード書く時とか便利。
let(:today) {"2012-12-13".to_date} #=> Thu, 13 Dec 2012
Array#forty_two
人生、宇宙、すべての答えを出してくれるメソッドだと思うw
(確証は無いけど)
人生、宇宙、すべての答え - Wikipedia
http://ja.wikipedia.org/wiki/%E4%BA%BA%E7%94%9F%E3%80%81%E5%AE%87%E5%AE%99%E3%80%81%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E7%AD%94%E3%81%88