なるようになるブログ

読書感想文かrailsについてかrubyについてか

rails commit log流し読み(2015/07/20)

2015/07/20分のコミットです。

CHANGELOGにのったコミットは以下の通りです。

activesupport/CHANGELOG.md

activerecord/CHANGELOG.md

actionpack/CHANGELOG.md


Fix TimeWithZone#eql? to handle TimeWithZone created from DateTime

activesupport/lib/active_support/time_with_zone.rbの修正です。

TimeWithZone#eql?メソッドを、DateTimeクラスから生成したTimeWithZoneクラスと正しく比較処理が行えるよう修正しています。

# before

twz = DateTime.now.in_time_zone
twz.eql?(twz.dup) => false

# after

twz = DateTime.now.in_time_zone
twz.eql?(twz.dup) => true

元々eql?メソッドでは、内部でDateTimeクラスのオブジェクトを生成して、そのオブジェクトのeql?メソッドと引数のクラスが同じかどうか比較していました。その為、eql?メソッドTimeWithZoneクラスを渡した場合に、DateTimeクラスとTimeWithZoneで比較が行われてしまい、正しく比較処理が行えていませんでした。

引数のeql?メソッドを使って比較するようにし、正しくDateTimeクラス同士で比較処理が行われるよう修正しています。


Fix counter_cache for polymorphic associations

activerecord/lib/active_record/associations/builder/belongs_to.rbの修正です。

polymorphic associationsを使用している場合に、counter cacheが正しく動作しないバグがあったのを修正しています。

counter cacheを更新する処理に、そもそもassociationがpolymorphicだった場合の処理が入っていなかったようです。


Fix the test that was broken by #16445 rather than deleting it

activerecord/test/cases/locking_test.rbの修正です。

先のcounter cacheの対応で誤って削除してしまったpolymorphic associationsを削除した場合のテストを戻しています。


Merge pull request #20936 from repinel/fix-params-fetch-exception-overwritten

actionpack/lib/action_controller/metal/strong_parameters.rbの修正です。

Parameters#fetchメソッド全体でKeyErrorをrescueし、ActionController::ParameterMissingをraiseしていたのを、ブロックが渡されなかった場合のみActionController::ParameterMissingをraiseするよう修正しています。

     def fetch(key, *args, &block)
       convert_hashes_to_parameters(
         key,
-        @parameters.fetch(key, *args, &block),
+        @parameters.fetch(key) {
+          if block_given?
+            yield
+          else
+            args.fetch(0) { raise ActionController::ParameterMissing.new(key) }
+          end
+        },
         false
       )
-    rescue KeyError
-      raise ActionController::ParameterMissing.new(key)
     end

fetchメソッドにブロックを渡して、かつブロックの中でKeyErrorをraiseさせる、という処理を行った場合に、予想外にParameterMissingがraiseされて困る、という問題があった為修正したとの事です。


Freeze string literals when not mutated.

性能向上の為に、値が変化しないStringクラスをfreezeするよう修正しています。

freeze したい場合としない場合との性能差は下記のとおりです。

require 'benchmark/ips'

number_of_objects_reduced = 1_114

Benchmark.ips do |x|
  x.report("freeze")    { number_of_objects_reduced.times { " ".freeze } }
  x.report("no-freeze") { number_of_objects_reduced.times { " " } }
end

We get the results

Calculating -------------------------------------
              freeze     1.428k i/100ms
           no-freeze   609.000  i/100ms
-------------------------------------------------
              freeze     14.363k (± 8.5%) i/s -     71.400k
           no-freeze      6.084k (± 8.1%) i/s -     30.450k

なお、freezeして良いかどうかの調査用に作られたライブラリがこちら。れりごー。


Fix tests broken by previous commit

activesupport/lib/active_support/inflector/methods.rbの修正です。

先のコミットの修正にタイポがあったのを修正しています。


Add missing method name to exception description

activerecord/lib/active_record/associations/collection_proxy.rbの修正です。

CollectionProxy#prependメソッドが出力するエラーメッセージ内の代わりに使用するメソッドの一覧にpushメソッドが漏れていたのを追加しています。

-        raise NoMethodError, "prepend on association is not defined. Please use << or append"
+        raise NoMethodError, "prepend on association is not defined. Please use <<, push or append"

fix doc about ActiveRecord::Transactions::ClassMethods#transaction [ci skip]

activerecord/lib/active_record/transactions.rbのdocの修正です。

transactionメソッドdocに記載されている、参照先のdocのメソッド名が誤っていたのを修正しています。


Merge pull request #20384 from kaspth/per-request-cache

ActionViewの修正です。

development modeの場合、digest cacheがリクエスト単位で有効になるよう修正しています。

元々、テンプレートが呼ばれる度にdigest cacheの生成が行われており、同じリクエスト内で同じテンプレートが複数呼ばれた場合でも、呼ばれる度にdigest cacheの生成が行われていました。ただ、今回の対応により、同じリクエストで同じテンプレートが複数呼ばれた場合は、最初の一度だけdigest cacheの生成が行われ、後は最初に生成したdigestが使いまわされるようになりました。


Merge pull request #20895 from brian-davis/brian-davis

actionview/lib/action_view/helpers/capture_helper.rbのdocの修正です。

CaptureHelper#content_forメソッドのdoc内のグラマー修正を行っています。