なるようになるブログ

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

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

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

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

actionpack/CHANGELOG.md

railties/CHANGELOG.md

activerecord/CHANGELOG.md


remove dead code

actionpack/lib/action_dispatch/middleware/cookies.rbの修正です。

使用してなくなったCookieJar#recycle!メソッドを削除しています。


Adds missing argument handling for ActionController::TestSession to

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

ActionController::TestSession#fetchメソッドに2つ以上の引数 or ブロックを渡した場合に、ArgumentErrorがraiseされてしまう問題があったのを、TestSession#fetchメソッドで正しく引数をハンドリングするよう修正しています。


Small fix

rails guideのAction Mailer Basicsの修正です。

Sending Email To Multiple Recipientsの項のexampleコードで、Mailerクラスの親クラスが、実際生成される親クラスと異なっていたのを修正しています。


better docs for ActiveRecord::Migration#table_name_options

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

ActiveRecord::Migration#table_name_optionsメソッドにdocを追加しています。


Merge pull request #21131 from eagletmt/percent-filename

actionpack/lib/action_dispatch/http/upload.rbの修正です。

途中に"%"が含まれているUTF-8のマルチバイトなファイル名(ex: "ファイル%名.txt")のファイルをアップロードした際に、Encoding::UndefinedConversionErrorが発生してしまう問題があったのを修正しています。

Railsのファイルアップロード処理では、4.2からファイル名が全てUTF-8にencode可能な状態を想定するようになった(Rack側でエスケープ処理済みの想定)ので、実際はエスケープ済みになってない為、エラーになってしまっていたようです。


Merge pull request #21061 from yui-knk/refactor/route_set

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

Generator::PARAMETERIZEから2回行われていたArray#to_paramメソッドの呼び出しを削除しています。


Merge pull request #21043 from y-yagi/loading_fixtures_in_engine_integration_tests

railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rbの修正です。

Rails Engine用のtest_helper.rbでActionDispatch::IntegrationTest.fixture_pathにfixtures のパスが正しく設定されていなかったのを、正しいパスが設定されるよう修正しています。


Only load statistics.rake once from inside engine

railties/lib/rails/tasks.rbの修正です。

デフォルトで生成されるrakeファイルを使用してRails Engine配下でrakeコマンド実行した際に、warning: already initialized constant STATS_DIRECTORIESのワーニングが表示される問題があったのを修正しています。

ロード処理の都合上、statistics.rakeファイルのロードが2回発生してしまうのですが、statistics.rakeではSTATS_DIRECTORIESをグローバルに定義している為、ワーニングが出てしまってました。task.rbstatisticsがロード済みの場合、ロード処理を行わないよう対応を行っています。これ、根本的には、STATS_DIRECTORIESがグローバルに定義されているのが問題な感があります。


Merge pull request #21092 from vngrs/use_memoization_for_ids_reader

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

CollectionAssociation#ids_readerメソッドで、一度取得したassociationのidsをインスタンス変数に保持するよう修正しています。 値を複数参照する際に、不要なqueryが発行されないようにする為、修正しています。


use a request object to reduce string allocations and not know about ENV keys

actionpack/lib/action_dispatch/middleware/static.rbの修正です。

Static#callメソッドPATH_INFOを取得する際、env hashからではなく、request objectから情報を取得するよう修正しています。

不要なString objectの作成を避ける為、及びenv hashへの直接のアクセスを避ける為。


get the underlying REQUEST_METHOD from the superclass

Request#request_methodメソッドで、REQUEST_METHODを取得するのに、env hashからではなく、親クラス(Rack::Request)から値を取得するよう修正しています。


reuse the request object in the File serving middleware

ActionDispatch::FileHandlerクラスとActionDispatch::Staticクラスで、作成済みのrequest objectを使いまわせるよう、FileHandler#serveメソッドを新規に作成し、元々callメソッドで行っていた処理をそちらで行うよう修正しています。


Merge pull request #20459

activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rbの修正です。

migrationにPostgreSQLのgeometric data types を指定出来るよう対応しています。

create_table :foo do |t|
  t.line :foo_line
  t.lseg :foo_lseg
  t.box :foo_box
  t.path :foo_path
  t.polygon :foo_polygon
  t.circle :foo_circle
end

ただ、あくまで、定義出来るという状態になっただけで、Railsとしてそれぞれの型に対して特別な対応がされているわけでは無い状態との事です。(今後正式なサポートをやる予定はあるとの事)


prevent string allocations

actionpack/lib/action_dispatch/http/request.rbの修正です。

Requestクラスのenv hashアクセス用メソッドで、envのkeyをfreezeして、不要なString objectが生成されないよう改善しています。


ExceptionWrapper doesn't need to know about env

ActionPackの修正です。

ExceptionWrapperコンストラクタの第一引数をenv Hashからbacktrace_cleanerに変更しています。

元々env hashからbacktrace_cleanerの情報('action_dispatch.backtrace_cleaner')を取得するためにenv hashをコンストラクタに渡していたのですが、 必要なのはbacktrace_cleanerの情報だけだったので、env hashを渡す必要は無いだとうとの事で修正したようです。


ask the request if we should show exceptions

ActionPackの修正です。

Requestクラスに、exceptionを表示する/しないを確認する為のshow_exceptions?を追加して、 env hashを直接参照するのではなく、左記のメソッドを使用するよう修正しています。


use a request object to access info from env in GetIp

ActionPackの修正です。

Requestクラスにremote_ip用のメソッドを追加し、IP関連の情報(HTTP_CLIENT_IPREMOTE_ADDR)を取得する際、env hashを直接参照するのではなく、request object経由で値を取得するよう修正しています。


Added bin/update script to update application automatically

railtiesの修正です。

development環境のupdateを行う為の、bin/update scriptを追加しています。中身は下記の通りです。

require 'pathname'
require 'fileutils'
include FileUtils

# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)

def system!(*args)
  system(*args) || abort("\n== Command #{args} failed ==")
end

chdir APP_ROOT do
  # This script is a way to update your development environment automatically.
  # Add necessary update steps to this file.

  puts '== Installing dependencies =='
  system! 'gem install bundler --conservative'
  system 'bundle check' or system! 'bundle install'

  puts "\n== Updating database =="
  system! 'bin/rake db:migrate'

  puts "\n== Removing old logs and tempfiles =="
  system! 'bin/rake log:clear tmp:clear'

  puts "\n== Restarting application server =="
  system! 'bin/rake restart'
end

gemのインストール、db:migrate、logとtmpファイルのクリアーをまとめてやってくれる感じです。割と便利そうかも。


Fix documentation on ActionDispatch::Request

actionpack/lib/action_dispatch/http/request.rbのdocの修正です。

ActionDispatch::Requestで動的に生成しているメソッドに記載しているdocが、実際の処理と異なってしまっていたのを修正しています。


Merge pull request #21153 from grosser/grosser/ports

actionpack/lib/action_dispatch/testing/integration.rbの修正です。

Session#processメソッドで、HTTP_HOSTに不要なportの情報を付加していたのを、実際のwebserver同様、付加しないよう修正しています。


speed up code and avoid unnecessary MatchData objects

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

Inflections#uncountable?メソッド正規表現でマッチ処理を行う際、String#matchではなく、String#=~を使用する修正しています。

String#=~の方が早いとの事。ベンチ。

require 'benchmark/ips'

def fast
  "foo".freeze =~ /boo/
end

def slow
  "foo".freeze.match(/boo/)
end

Benchmark.ips do |x|
  x.report("String#=~") { fast }
  x.report("String#match") { slow }
  x.compare!
end
Calculating -------------------------------------
           String#=~    69.889k i/100ms
        String#match    66.715k i/100ms
-------------------------------------------------
           String#=~      1.854M (±12.2%) i/s -      9.155M
        String#match      1.594M (±11.0%) i/s -      7.939M

Comparison:
           String#=~:  1853861.7 i/s
        String#match:  1593971.6 i/s - 1.16x slower

[ci skip] Remove identity.active_record

rails guideのActive Support Instrumentationの修正です。

既に存在しないidentity.active_record フックについての説明を削除しています。


Add ActiveRecord::Relation#in_batches

ActiveRecordの修正です。

batch処理用のメソッドとして、ActiveRecord::Relation#in_batchesを追加しています。

元々ActiveRecordにはbatch処理用のメソッドとして、find_eachfind_in_batchesメソッドがありました。これらのメソッドは、一つ一つのレコードに対して処理を行う為のメソッドでした。

# `find_each`メソッドの戻り値は`Enumerator`
Person.find_each do |person|
  # 一つ一つのpersonレコードに対して何か処理
end

対して、in_batchesは、relationに対して処理を行う為のメソッドになっています。

# `in_batches`メソッドの戻り値は、新規に作成された`ActiveRecord::Batches::BatchEnumerator`

Person.in_batches.each_record(&:party_all_night!)
Person.in_batches.update_all(awesome: true)
Person.in_batches.delete_all
Person.in_batches.each do |relation|
  relation.delete_all
  sleep 10 # Throttles the delete queries
end

in_batchesに指定可能なオプションは、下記4つです。

:of - Specifies the size of the batch. Default to 1000.
:load - Specifies if the relation should be loaded. Default to false.
:begin_at - Specifies the primary key value to start from, inclusive of the value.
:end_at - Specifies the primary key value to end at, inclusive of the value.

batch処理、基本的に対象となる全てのレコードに同じ処理を行う事が多いので、割と使いそうな気がします。


Only invoke the default block for mattr_accessor once so that it does not cause issues if it is not idempotent

activesupport/lib/active_support/core_ext/module/attribute_accessors.rbの修正です。

mattr_accessorメソッドmattr_writerメソッドを呼び出す際、引数のブロックを渡さないよう修正しています。

     mattr_reader(*syms, &blk)
-    mattr_writer(*syms, &blk)
+    mattr_writer(*syms)

デフォルトを渡す為のブロックなのですが、既にmattr_readerで設定されており、2回呼ばれると期待してない動作になってしまうので、呼ばない方が良いのでは、という事で修正されたようです。

count = 0
@module.cattr_accessor(:defcount){ count += 1 }
count # => 2になってしまっていた

Fix doc typo

rails guideのA Guide for Upgrading Ruby on Railsの修正です。

inheritinherentにタイポしていたのを修正しています。


move flash hash access to methods on the request object

actionpack/lib/action_dispatch/middleware/flash.rbの修正です。

flash hashにアクセスする為のメソッドをrequest classに追加し、そちらからflashの値を取得するよう修正しています。


refactor param parsing middleware to use request objects

actionpack/lib/action_dispatch/http/request.rbactionpack/lib/action_dispatch/middleware/params_parser.rbの修正です。

action_dispatch.request.request_parametersaction_dispatch.loggerの取得・設定用メソッドをrequest classに追加し、env hashを直接参照するのではなく、そちらのメソッド経由で値を取得するよう修正しています。