なるようになるブログ

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

rails commit log流し読み(2014/12/23)

2014/12/23分のコミットです。

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

activerecord/CHANGELOG.md


Remove this line since we are using Rake to run our tests [ci skip]

rails guideのA Guide to Testing Rails Applicationsの修正です。

テスト実行時にtest_helper.rbがあるディレクトリを-Iオプションに指定するように説明が記載されていたのですが、rakeでテストを実行する際、明示的にパスを渡す必要は無いので、記述を修正しています。


I'm sorry but I would rather not link to a 7 year old blog post [ci skip]

rails guideのA Guide to Testing Rails Applicationsの修正です。

7年以上前の古いブログの記事へのリンクがあったので、流石に古いだろうという事で削除しています。


Add subheadings for these sections [ci skip]

rails guideのA Guide to Testing Rails Applicationsの修正です。

見出しとして、Your first failing testWhat an error looks likeを追加しています。本文はそのまま。


Use serve_static_files in guides [skip ci]

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

config.serve_static_files -> config.serve_static_assetsに修正しています。


Use serve_static_files in guides, take 2 [skip ci]

rails guideのConfiguring Rails Applicationsの修正です。

config.serve_static_files -> config.serve_static_assetsに修正しています。 2回目。


Remove this section, it adds no real value [ci skip]

rails guideのA Guide to Testing Rails Applicationsの修正です。

What to Include in Your Unit Testsの項を削除しています。

good practiveとして、modelのすべてのメソッド、validationについてテストするよう記載してあったのです、それは意味が無いだろう、という事で削除されたようです。


Correctly handle limit on int4 and int8 types in PG

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

Rails 4.2で、PostgreSQLでintegerを使用している、かつlimitに4又は8を指定している場合に、limitが正しく扱えてなかったバグがあったのを修正しています。


Do not use line breaks on notes [ci skip]

rails guideのActive Record Query InterfaceRuby on Rails Security Guideの修正です。

NOTEから改行を削除しています。改行を追加すると、生成されたHTML上不適切な位置での改行が発生してしまうので、削除したようです。


Add force: true to table created in tests

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

テスト用のテーブルを作成する際に、force: trueオプションを使用するよう修正しています。テストを途中で終了した際に、手で削除する必要がある為との事です。


Only add debugger/byebug if on MRI

railties/lib/rails/generators/rails/plugin/templates/Gemfileの修正です。

rails pluginを作成する際、MRIの時のみdebugger/byebugをGemfileに記載するよう修正しています。 因みにこれはrails pluginの対応のみで、rails newの時の対応は後ほどです。


Skip byebug on all non-MRI rubies, fix tests

railties/lib/rails/generators/rails/app/templates/Gemfileの修正です。

rails appを作成する際、MRIの時のみdebugger/byebugをGemfileに記載するよう修正しています。


Convert references to kwargs

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

referencesメソッドの引数が可変長引数一つだけだったのを、複数引数指定するよう修正しています。

-      def references(*args)
-        options = args.extract_options!
-        polymorphic = options.delete(:polymorphic)
-        index_options = options.delete(:index)
-        type = options.delete(:type) || :integer
+      def references(
+        *args,
+        polymorphic: false,
+        index: false,
+        type: :integer,
+        **options
+      )
+        polymorphic_options = polymorphic.is_a?(Hash) ? polymorphic : options
+        index_options = index.is_a?(Hash) ? index : {}

Add a foreign_key option to references while creating the table

ActiveRecordの修正です。

referencesメソッドに、foreign_keyオプションを設定出来るように対応しています。

# before
create_table :posts do |t|
  t.references :user
end
add_foreign_key :posts, :users

# after
create_table :posts do |t|
  t.references :user, foreign_key: true
end

記述としては分り易くなってますね。しかし、4.2で追加になったばかりなのに、もう設定方法が変わるとは…。


Convert add_references to use kwargs

activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rbの修正です。

add_referencesメソッドの引数が可変長引数一つだけだったのを、複数引数指定するよう修正しています。

-      def add_reference(table_name, ref_name, options = {})
-        polymorphic = options.delete(:polymorphic)
-        index_options = options.delete(:index)
-        type = options.delete(:type) || :integer
+      def add_reference(
+        table_name,
+        ref_name,
+        polymorphic: false,
+        index: false,
+        type: :integer,
+        **options
+      )
+        polymorphic_options = polymorphic.is_a?(Hash) ? polymorphic : options
+        index_options = index.is_a?(Hash) ? index : {}

Add foreign_key as an option to references for change_table

ActiveRecordの修正です。

add_referencesメソッドforeign_keyオプションを指定出来るよう修正しています。

add_reference(:products, :supplier, foreign_key: true)

Use the new foreign_key option on references in generators

generatorsの修正です。

先に追加したreferencesメソッドforeign_keyオプションを使用するようgeneratorを修正しています。

rails g model Post user:references

を実行した際の結果が、以下のように変更になっています。

# before
def change
  create_table :posts do |t|
    t.references :user, index: true
  end

  add_foreign_key :posts, :users
end

# after
def change
  create_table :posts do |t|
    t.references :user, index: true, foreign_key: true
  end
end

また、add_xxxも同様に対応されています。

rails g migration add_user_to_posts user:references
# before
def change
  add_reference :posts, :users, index: true
  add_foreign_key :posts, :users
end

# after
def change
  add_reference :posts, :users, index: true, foreign_key: true
end

Add test missed by a03ea684efc3505647cf0327a501aa2dbb591ad2

railties/test/generators/migration_generator_test.rbの修正です。

先のgeneratorの対応で追加したテストの確認内容に誤りがあったのを修正しています。


Don't wrap create_table in a transaction for tests which run on MySQL

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

テストの中で、transactionの中でcreate_tableをするようにしていたのですが、MySQLだとエラーになってしまうので、transactionを削除しています。


Don't calculate all in-place changes to determine if attribute_changed?

activemodel/lib/active_model/dirty.rbactiverecord/lib/active_record/attribute_methods/dirty.rbの修正です。

attribute_changed?を呼び出した際すべてのattributeについて変更があったかチェックを行っていたのを、対象のattributeのみ変更があったか確認するよう修正しています。

4.2.0で、4.1.8と比べて性能劣化してしまっていたの対応との事です。


Don't perform statement caching for find when called from a scope

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

Rails 4.2で、独自にfind_xxxというメソッド名のメソッドを作成した場合に、そのメソッドの戻り値がおかしな値になるバグがあったのを修正しています。

issueより。

class User < ActiveRecord::Base
  has_many :user_folders
end

class UserFolder < ActiveRecord::Base
  belongs_to :user
  def self.find_by_id_and_do_stuff(id)
    existing = self.find(id)
    # do stuff
  end
end
user.user_folders.find_by_id_and_do_stuff(user_folder.id) # Populate statement_cache
#=> UserFolder Load (0.2ms)  SELECT  "user_folders".* FROM "user_folders" WHERE "user_folders"."user_id" = ? AND "user_folders"."id" = ? LIMIT 1  [["user_id", 1], ["id", 1]]
user2.user_folders.find(user_folder2.id) # Works
#=> UserFolder Load (0.0ms)  SELECT  "user_folders".* FROM "user_folders" WHERE "user_folders"."user_id" = ? AND "user_folders"."id" = ? LIMIT 1  [["user_id", 2], ["id", 2]]
user2.user_folders.find_by_id_and_do_stuff(user_folder2.id) # Fetches incorrectly cached user_id
#=> UserFolder Load (0.1ms)  SELECT  "user_folders".* FROM "user_folders" WHERE "user_folders"."user_id" = ? AND "user_folders"."id" = ? LIMIT 1  [["user_id", 1], ["id", 2]]

不正なstatement cacheが作成されてしまったのが問題だったようです。AdequateRecordの影響ですかねえ。


Improve the performance of reading belongs_to associations activerecord/lib/active_record/associations/belongs_to_association.rbの修正です。

Rails 4.2.0で、belongs_to associationの読み込み処理が4.1.8と比べて劣化してしまっていたのを改善しています。

ActiveRecord::Base#[]が遅くなってしまっているとの事で、activerecord/lib/active_record/associations/belongs_to_association.rbでは[]の代わりに_read_attributeメソッドを使用するよう修正しています。


Better tests for AV::RecordIdentifier

actionview/test/template/record_identifier_test.rbの修正です。

ActionView::RecordIdentifierクラスのテストを追加しています。


Describe gotcha for 'status' option [ci skip]

rails guideのLayouts and Rendering in Railsの修正です。

renderメソッドstatusオプションについての説明を追加してます。


Fixing numeric attrs when set to same negative value

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

4.2.0でnumeric型のattributeに同じ負の値を設定をした場合に、変更されている、と誤ってマークされてしまったバグがあったのを修正しています。

class Person < ActiveRecord::Base
  # age          :integer(4)
end

person = Person.new(age: -1)
person.age = -1
person.changes
=> { "age" => [-1, -1] }
person.age_changed?
=> true

更新されたかどうかを判定する正規表現で、"-"が考慮されてなかったのが問題のようです。


fix typo in nodoc

actionmailer/lib/action_mailer/delivery_job.rbのdocの修正です。

:nodoc -> :nodoc:に修正しています。


cleanup CHANGELOGs. [ci skip]

actionpack/CHANGELOG.mdactiverecord/CHANGELOG.mdの修正です。

表記ゆれを整えています。


Add information about "allow_destroy" requiring an ID. [ci skip]

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

accepts_nested_attributes_forメソッドallow_destroyオプションを使用する場合、削除対象のIDを指定する必要がある旨説明を追加しています。


Replace deprecated #load_schema with #load_schema_for.

activerecord/lib/active_record/railties/databases.rakeactiverecord/lib/active_record/tasks/database_tasks.rbの修正です。

ActiveRecord::Tasks::DatabaseTasks#load_schema_forがdeprecateになり、内部では代わりにActiveRecord::Tasks::DatabaseTasks#load_schemaを使用するよう修正しています。


docs, replace ` with + for proper rdoc output. [ci skip]

activerecord/lib/active_record/attributes.rbactiverecord/lib/active_record/type/value.rbのdocの修正です。

doc上の""を"+"に修正しています。""はrdoc記法では無い為ですね。


Merge Pull Request #18157

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

datetime型のカラムに不正日付のデータを設定した際に、ArgumentErrorが発生していたのを、ArgumentErrorをおこすのではなく、nilを設定するよう修正しています

# before
task = Task.new(start_at: "2014-07-01T24:59:59GMT")   #=> ArgumentError

# after
task = Task.new(start_at: "2014-07-01T24:59:59GMT")   #=> エラー無し
taks.start_at      #=> nil

元々、テキスト等のそもそも日付ではない値を設定された場合もnilになっていたとの事です。

task = Task.new(start_at: "rubbish")
taks.start_at      #=> nil

うーん。ArgumentErrorのままでも良さそうな気がするんですけどねえ。


Changelog for 99a6f9e60ea55924b44f894a16f8de0162cf2702

activerecord/CHANGELOG.mdの修正です。

先に追加されたforeign_keyオプションの対応について、CHANGELOGに追記しています。


Remove block from super

actionview/lib/action_view/helpers/tags/search_field.rbactionview/lib/action_view/helpers/tags/text_field.rbの修正です。

SearchFieldのオプション処理をblock内で実行していたのを、block無しで行うようリファクタリングしています。@options変数に、オプション処理後の値の設定漏れがあったらしく、ついでにリファクタリングを行ったようです。


Fix connection leak when a thread checks in additional connections.

activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rbの修正です。

DBのconnectionがリリースされないバグがあったのを修正しています。

connection_1 = ActiveRecord::Base.connection
connection_2 = ActiveRecord::Base.connection_pool.checkout
ActiveRecord::Base.connection_pool.checkin(connection_2)
connection_3 = ActiveRecord::Base.connection

上記のような処理を行った場合、最初に取得したconnection_3を取得した際に、connection_1がリリースされず、timeoutになるまで保持し続けてしまっていたようです。