なるようになるブログ

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

rails commit log流し読み(2015/12/15)

2015/12/15分のコミットです。

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

activerecord/CHANGELOG.md


Deprecate limit strings with commas

activerecord/lib/active_record/relation/query_methods.rbの修正です。

ActiveRecord::QueryMethods#limitにカンマ区切りの値を渡すのはdeprecateになりました。

LIMIT 1,2 ってLIMIT 1 OFFSET 2と評価されるんですねえ。知らなかった。今後は普通にoffsetメソッドを使用するように、との事です。


Make Parameters#to_h and #to_unsafe_h return HWIA

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

ActionController::Parameters#to_hActionController::Parameters#to_unsafe_hメソッドHashWithIndifferentAccessを返すよう修正しています。

Rails 4.2よりActionController::Parameters#to_hメソッドHashWithIndifferentAccessではなくHashを返すようになったのですが、それにより既存のコードが壊れてしまった、という報告があった為、再度HashWithIndifferentAccessを返すよう戻したようです。issue: changing ActionController::Parameters#to_h was a desaster · Issue #21391 · rails/rails


Use a bind param for LIMIT and OFFSET https://github.com/rails/rails/commit/574f255629a45cd67babcfb9bb8e163e091a53b8 activerecord/lib/active_record/relation/query_methods.rbの修正です。

limitoffsetでbind paramを使用するよう修正しています。

paginationのような、他のSQLは同じでlimitoffsetだけ違うようなSQLの場合に、生成されるprepared statementsの量が大分減らせるようになるようです。


ActiveRecord::Base#becomes should copy the errors

activemodel/lib/active_model/errors.rbactiverecord/lib/active_record/persistence.rbの修正です。

ActiveRecord::Base#becomesを呼び出した際、エラー(ActiveModel::Errors)の情報も保持するよう修正しています。


Fix test failures caused by 574f255

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

Use a bind param for LIMIT and OFFSETの対応で既存のテストの修正漏れがあったのを対応しています。


Perform a more efficient query in Relation#any?

activerecord/lib/active_record/relation.rbactiverecord/lib/active_record/relation/finder_methods.rbの修正です。

ActiveRecord::FinderMethods#exists?メソッドを呼び出した際に、polymorphic associationをeager load済みの場合にtableを結合した状態を組み立てるよう修正しています。

Relation#any?でより効率的なqueryを実行出来るようにする為だったようなのですが、問題があった為、後ほどrevertされています。


Update seeds.rb.tt

railties/lib/rails/generators/rails/app/templates/db/seeds.rb.ttの修正です。

デフォルトで生成されるseeds.rbに記載されているexampleコードを更新しています。

-#   cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
-#   Mayor.create(name: 'Emanuel', city: cities.first)
+#   movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
+#   Character.create(name: 'Luke', movie: movies.first)

Rahm Emanuel doesn't deserve to be in Railsとの事なのですが、この辺りのニュアンスはよくわからない…。


Revert "Perform a more efficient query in Relation#any?"

Perform a more efficient query in Relation#any?をrevertしています。

eager_loadreferencesメソッドは引数にHashを渡す事が出来、Hashを渡された場合に正しく動作しない為、との事です。


Merge pull request #22564 from maximeg/legit_name_errors

actionpack/lib/action_dispatch/routing/route_set.rbの修正です。

ActionDispatch::Routing::RouteSet::Dispatche#serveメソッドでエラーが置きた際、NameErrorをrescueしてActionController::RoutingErrorにまるめていたのをやめて、ActionController::RoutingErrorのみrescueするよう修正しています。

-        rescue NameError => e
+        rescue ActionController::RoutingError
           if @raise_on_name_error
-            raise ActionController::RoutingError, e.message, e.backtrace
+            raise

NameErrorをrescueするとNoMethodErrorもrescueされてしまう為、本当に存在しないメソッドをアクセスした場合でもActionController::RoutingError(404)に丸められてしまっていた為、正しくエラー情報は渡されるようにする為に修正したようです。


Test with Ruby 2.3.0

.travis.ymlの修正です。

Travis CIでRuby 2.3.0-preview2でテストを実行するよう修正しています。が、直後に更新されています。


Do now allow failures with Ruby 2.3 anymore

.travis.ymlの修正です。

Ruby 2.3.0-preview2でテストを実行するのではなく、allow_failuresのリストからruby-headを削除しています。これにより、ruby-headでテストがコケた場合に、ちゃんとCIが赤くなるようになっています。


Remove ActionView::Helpers::CacheHelper#fragment_cache_key

actionpack/lib/action_controller/caching/fragments.rbactionview/lib/action_view/helpers/cache_helper.rbの修正です。

ActionView::Helpers::CacheHelper#fragment_cache_keyメソッドを削除しています。

Merge multi_fetch_fragments. · rails/rails@e56c635ActionView::Helpers::CacheHelper#fragment_cache_keyメソッドが追加されたのですが、既に同等のActionController::Caching::Fragments#fragment_cache_keyメソッドがあったので、そちらを使用するよう修正しています。


Add ruby-head back in the allow failures group

.travis.ymlの修正です。

先ほどallow_failuresのリストからruby-headを削除したのですが、travis CI上で実行されるruby-headのコードが古く、ruby-headのテストがfailしてしまう為、再度allow_failuresのリストに戻しています。


Fix travis matrix

.travis.ymlの修正です。

先の修正でruby-headの指定の仕方を誤っていた為修正しています。


Add fragment_cache_key macro for controller-wide fragment cache key prefixes

actionpack/lib/action_controller/caching/fragments.rbの修正です。

controller全体に関わるfragment cache key prefixeを設定出来るよう対応しています。

class ApplicationController < ActionController::Base
  fragment_cache_key "v1"
end

割と便利そう。PRによると、既にBasecamp 3で使用している機能との事です。


Ensure uuid-ossp extension is present before we rely on it

activerecord/test/cases/adapters/postgresql/uuid_test.rbの修正です。

uuidのテストで、テストの前処理でuuid-osspを有効化するよう修正しています。


Add migration versioning via Migration subclasses

Active Recordの修正です。

migrationファイルにmigrationのバージョン情報を付与するよう修正しています。

rails 5以降では、generatorが生成するmigrationファイルに、デフォルトで以下のようなバージョン情報が付与するようになります。

class CreateTodos < ActiveRecord::Migration[5.0]
  def change
    create_table :todos do |t|
      t.string :title
      t.text :text
      t.references :user, index: true, foreign_key: true

      t.timestamps
    end
  end
end

これにより、railsのどのバージョンで生成されたmigrationファイルかわかるようになり、既存のmigrationの挙動は変えずにデフォルトの値を変える、という事が出来るようになります。


Use a deliberately-invalid migration version in all doc examples

Active Recordの各種docの修正です。

ActiveRecord::Migrationクラスのexampleに、migration versioningを追加しています。

-    class AddSystemSettings < ActiveRecord::Migration
+    class AddSystemSettings < ActiveRecord::Migration[0.0]

なお、0.0という不正な値を指定しているのは意図的で、Railsのバージョンがあがった際にいちいちexampleを更新しないで済むようにそうしたとの事です。が、後ほど修正しています。


Ensure generated migrations include a version number

各種テストの修正です。

migrationファイルを生成するテストで、生成されたファイルにバージョンナンバーが指定されている事のテストを追加しています。


Internal test migrations use the private 'Current' version

各種テストの修正です。

Migrationクラスを使用するテストでActiveRecord::Migration::Currentクラスを使用するよう修正しています。

特定のバージョンに依存しないテストであり、バージョンを指定してしまうとrailsのバージョンを上げる度に更新する必要がある為、現在のバージョンである事を表したActiveRecord::Migration::Currentを使用するようにしています。


Find the delegate, even in a deeper inheritance tree

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

migration処理でdelegate先を探す際に、親クラスを再帰的に探すよう修正しています。


In 4.2 migrations, timestamps defaulted to null: true

activerecord/lib/active_record/migration/compatibility.rbの修正です。

rails 4.2のmigrationファイルでは、rails 4.2の挙動と同様に、timestampsのデフォルトをnull: trueとなるよう修正しています。


Schema uses current migration API

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

ActiveRecord::Schemaクラスの親クラスにActiveRecord::Migration::Currentを使用するよう修正しています。


Use a real migration version number in docs

Active Recordの各種docの修正です。

先ほどActiveRecord::Migrationクラスのexampleに0.0という不正な値を指定してたのを、5.0という正常な値を使用するよう修正しています。

-    class AddSystemSettings < ActiveRecord::Migration[0.0]
+    class AddSystemSettings < ActiveRecord::Migration[5.0]

リリースした際にまとめて更新すれば良いだろうというのと、その手間より、exampleにはコピーして直ぐ使える正常な情報が記載されている事の方が大事だろう、という事で修正されたようです。


remove extra spaces from deprecation message

activerecord/lib/active_record/attribute_methods/time_zone_conversion.rbactiverecord/lib/active_record/relation/query_methods.rbの修正です。

Active Recordで表示するdeprecateメッセージに、不要な空白が表示されてしまっていたのを、表示されないよう修正しています。

例。

# before
DEPRECATION WARNING:               Time columns will become time zone aware in Rails 5.1. This
              still causes `String`s to be parsed as if they were in `Time.zone`,
              and `Time`s to be converted to `Time.zone`.

              To keep the old behavior, you must add the following to your initializer:

                  config.active_record.time_zone_aware_types = [:datetime]

              To silence this deprecation warning, add the following:

                  config.active_record.time_zone_aware_types << :time
# after
DEPRECATION WARNING: Time columns will become time zone aware in Rails 5.1. This
still causes `String`s to be parsed as if they were in `Time.zone`,
and `Time`s to be converted to `Time.zone`.

To keep the old behavior, you must add the following to your initializer:

    config.active_record.time_zone_aware_types = [:datetime]

To silence this deprecation warning, add the following:

    config.active_record.time_zone_aware_types << :time