なるようになるブログ

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

rails commit log流し読み(2018/08/31)

2018/08/31分のコミットです。

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

railties/CHANGELOG.md

activerecord/CHANGELOG.md

activejob/CHANGELOG.md


Refactor attributes_for_{create,update} to avoid an extra allocation

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

attributes_for_updateメソッド、及び、attributes_for_createメソッドでreadonly attributeを除外するのにrejectを使用していたのを、delete_ifメソッドを使用するようリファクタリングしています。余分なオブジェクトの生成を減らせるようにする為。


Add migrations_paths option to migration generator

activerecord/lib/rails/generators/active_record/migration.rbactiverecord/lib/rails/generators/active_record/migration/migration_generator.rbの修正です。

migration generatorにmigrationファイルを生成するpathを指定する為の--migrations_pathsオプションを追加しています。

$ rails g migration CreateHouses --migrations_paths=db/kingston_migrate
      invoke  active_record
      create    db/kingston_migrate/20180830232057_create_houses.rb

複数DBを使っていて、migrationファイルをDB毎にわけたい時に使用する為に追加したとのことです。


[ci skip] Document permitted_scalar_filter

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

Parameters#permitted_scalar_filterメソッドにdocを追加しています。


Merge pull request #33637 from eileencodes/ar-connection-management-refactoring

Active Recordの修正です。

ActiveRecord::Base.configurationsの戻り値が元々はHashだったのを、ActiveRecord::DatabaseConfigurationsクラスのインスタントを返すよう修正、及び、関連している箇所の修正を行っています。

# before
ActiveRecord::Base.configurations
#=> { "development" => { "adapter" => "sqlite3", "database" => "db/development.sqlite3" } }

# after
ActiveRecord::Base.configurations
#=> <ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
      #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
        @spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>
      ]

ActiveRecord::DatabaseConfigurationsにはto_hメソッドがあり、元と同じようなHashが必要な場合、to_hメソッドを使用すれば取得出来るようになっています。複数DB対応の為のリファクタリング。今のところ完全に非互換な対応なので、ActiveRecord::Bae.configurationsを使用している場合注意が必要そうです。


Just delegate update with ids on a relation to klass.update

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

Relation#updateメソッドの引数に、idsとattributesを指定した場合に、指定したidに対して更新処理が行われるよう修正しています。

これは、Refactor attributes_for_{create,update} to avoid an extra allocationから出来なくなっていた挙動だったのですが、そもそもidsとattributesを指定した場合の挙動は保証されていませんでいた(ドキュメントに記載はなかった)。

が、どうもその挙動を期待していたコードが(Shopifyの)あった為、再度動作するよう修正しています。


Merge pull request #33751 from steves/add_retry_notifications_to_aj

activejob/lib/active_job/exceptions.rbactivejob/lib/active_job/logging.rbの修正です。

Active Jobのinstrumentation hookに、enqueue_retry.active_jobretry_stopped.active_jobdiscard.active_jobを追加しています。

名前の通り、retry jobがenqueueされた時、retry jobがstopした時、jobがdiscardされた時に、それぞれ実行されるようになっています。


[ci skip] Typo in form helpers guide

rails guideのAction View Form Helpersの修正です。

Security GuideSecuring Rails Applicationsに修正しています。


Remove redundant travel_back

activerecord/test/cases/dirty_test.rbactivesupport/test/metadata/shared_metadata_tests.rbの修正です。

テストの後処理でtravel_backを呼び出していたのを削除しています。Remove time stubs after each test以降、テストの後処理で自動でtravel_backが呼び出されるようになっている為。

rails commit log流し読み(2018/08/30)

2018/08/30分のコミットです。

CHANGELOGへの追加はありませんでした。


32% Faster Object#try

activesupport/lib/active_support/core_ext/object/try.rbの修正です。

Object#tryメソッドのリファクタリングです。元々はObject#try!メソッドを呼び出すしていたのですが、Object#try!メソッドを使用するのはやめて、Object#try内で処理を行うよう修正しています。

    def try(*a, &b)
-      try!(*a, &b) if a.empty? || respond_to?(a.first)
+      return unless a.empty? || respond_to?(a.first)
+      if a.empty? && block_given?
+        if b.arity == 0
+          instance_eval(&b)
+        else
+          yield self
+        end
+      else
+        public_send(*a, &b)
+      end

上記処理はObject#try!メソッド内で行っている処理をそのまま持ってきただけなのですが、try!を呼び出す際の*aのsplat処理を取り除けたことでArrayの生成処理を減らす事が出来、結果実行速度も上がっている、とのことです。

ベンチマークは[PR]https://github.com/rails/rails/pull/33747)参照。


Merge pull request #33748 from eileencodes/fix-erb-loading-issue-with-db-yaml

activerecord/lib/active_record/tasks/database_tasks.rbrailties/lib/rails/application/configuration.rbの修正です。

Application::Configuration#load_database_yamlメソッドを削除しています。

複数DBサポートの対応(Part 1 Easy Multi db in Rails: Add basic rake tasks for multi db setup)の延長でdatabase.ymlのパースタイミングが変わり、元々あった、database.ymlの中でRails.applicationの値を参照するテストがエラーになってしまいました(Rails.applicationが評価されるより前にファイルのパースが行われる為の筈)。で、その対応として、database.ymlをYAMLとしてだけパースし、erbの評価は行わない、というメソッド(#load_database_yaml)が追加されました。

が、このアプローチだと、下記のようにdatabase.ymlの中でerbを使って設定の分岐を行っているような場合に問題が発生してしまいました。

test:
  primary:
    <<: *default
    database: multiple_databases_test
  animals:
    <<: *default
    <% if something %> # This will break as it's invalid YML
    database: multiple_databases_test_animals
    migrations_paths: "db/animals_migrate"
    <% end %>

production:
  <% all_shards.each do |shard| %> # This will break as it's invalid YAML
  <%= shard.name %>:
    username: ...
  <% end %>

そのため、やはり最初にdatabase.ymlをロードする際にerbの評価も行うようにするよう修正をし、不要になった#load_database_yamlメソッドのは削除しています。なお、元々問題になっていたテストは、テストの内容を修正し対応しています。


Remove unused argument

railties/test/application/rake/dbs_test.rbの修正です。

db_create_and_dropメソッドから不要になった引数を削除しています。


Remove this conditional

railties/test/application/rake/dbs_test.rbの修正です。

先の処理で削除した引数を参照している箇所があったのを修正しています。参照はされているもの、引数が渡せることは無い為、不要なのは変わらず。


Faster time_value.rb

activemodel/lib/active_model/type/helpers/time_value.rbn修正です。

TimeValue#fast_string_to_timeメソッドのリファクタリングです。

マイクロ秒のパース処理で、文字列をRationalに変換 -> 1_000_000を乗算 -> Integerに変換、という流れで処理を行っていたのを、値が特定のフォーマット(.開始で7桁)の場合、.を削除し直接Integerに変換するよう修正しています。それ以外のフォーマットの場合、変わらず元の処理が使われます。

元の処理だと、値の乗算処理に時間が掛かってしまうため。


Merge pull request #33749 from schneems/schneems/faster-fragment

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

AbstractController::Caching::Fragments#combined_fragment_cache_keyメソッドでcache keyを生成するのにcompactを使用していたのを、flatten! + compact!を使用するようリファクタリングしています。不要なオブジェクトの生成を避ける為。


20% faster try

activesupport/lib/active_support/core_ext/object/try.rbの修正です。

trytry!メソッドの引数が全てArrayになっていたのを、最初の引数(method_name)を切り出しています。

-     def try(*a, &b)
-       return unless a.empty? || respond_to?(a.first)
-       if a.empty? && block_given?
+     def try(method_name = nil, *args, &b)
+       if method_name.nil? && block_given?

メソッド名以外の引数が無い場合にsplat処理が行われず、不要な配列の生成を抑止出来る為。


Merge pull request #33729 from kddeisz/plural-automatic-inverse

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

inverse associationsを取得する際に、association名が複数形の場合に正しく取得出来ていなかったのを、複数形の場合でも取得出来るよう修正しています。


Add missing require

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

テスト内で使用するmodelのrequireが不足していたのを追加しています。


Merge pull request #33757 from bogdanvlviv/follow-up-32937

docの修正です。

Signed / Encrypted cookiesにmetadataを指定出来るよう修正した、Purpose Metadata For Signed And Encrypted Cookiesのフォローアップとして、CHANGELOGのフォーマットの修正、config.action_dispatch.use_cookies_with_metadataについてConfiguring Rails Applications guideに説明を追加、Upgrading Ruby on Railsに説明を追加、を行っています。


Remove extra & self.class.column_names in keys_for_partial_write

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

Dirty#keys_for_partial_writeメソッドでcolumn nameの積を取得していたのを削除しています。呼び出し元のPersistence moduleで既に行っている為。


Remove attributes_with_values_for_{create,update} for internal use

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

AttributeMethods moduleからattributes_with_values_for_createメソッド及び、attributes_with_values_for_updateメソッドを削除しています。

attributes_with_values_for_updateはもう使われていない為。attributes_with_values_for_createまだ使われていたのですが、一箇所だけだったので、使用している箇所で処理を修正し対応しています。


Do not recompute length

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

Result#hash_rowsメソッドで、@rowsに対するイテレーションの中でcolumnの長さを取得していたのを、ループ前に値を取得するよう修正しています。

rails commit log流し読み(2018/08/29)

2018/08/29分のコミットです。

CHANGELOGへの追加はありませんでした。


Focus search input after page load on /rails/info/routes (#33683)

actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erbの修正です。

routes用のページ(/rails/info/routes)にアクセスした際に検索ボックスにフォーカスがあたるよう修正しています。


Add test to make sure the custom object key can't be serialized

activejob/test/cases/argument_serialization_test.rbの修正です。

customしたobject serializer keyはserialize出来ない事を確認するテストを追加しています。


Generate the same value as a label of view in system test template

railties/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.ttの修正です。

scaffoldで使用するsystem test用のテンプレートファイル内のattributeに対して値を入力する処理で、attributeに対してtitleizeメソッドを使用していたのを使用しないよう修正しています。

Capybaraのfill_inメソッドを使用して値を入力するコードなのですが、scaffoldで使用するviewのテンプレートファイルではtitleizeを使用しておらず、system testの方だけtitleizeを使用すると、viewで生成されるlabelとattribute名が一致せず、結果テストを実行するとエラーになってしまう、という問題があった為。


Merge pull request #33718 from kddeisz/permit-list

各コードでblacklist / whitelistという言葉を使用していたのを、permitted list / restricted listを使用するよう修正しています。

Merge pull request #33681 from minaslater/replace-white-and-blacklist ではdocの修正がメインでしたが、こちらはコードの修正メイン。


Add "Ruby on Rails 6.0 Release Notes" guide [ci skip]

rails guideのRuby on Rails 6.0 Release Notesを追加しています。

書かれているのはParallel Testingについての説明だけで、とりあえず雛形を追加しただけの状態です。


Prevent leaking of user's DB credentials on rails db:create failure

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

rails db:createでエラーになった際に、エラーメッセージ内でconfigの内容をそのまま表示していたのを、テーブル名だけ表示するよう修正しています。

configの内容にはDB接続用のパスワードも含まれており、セキュリティ的に良くないだろう、という理由の為。

rails commit log流し読み(2018/08/28)

2018/08/28分のコミットです。

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

activemodel/CHANGELOG.md


Update "Action View Form Helpers" guide [ci skip]

rails guideのAction View Form Helpersの修正です。

各項の言い回しやグラマー修正、exampleコードに誤りがあったのを修正、等を行っています。


Add documentation for :collation column option (#33733)

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

add_columnメソッドのdoc内の使用出来るオプションについて説明している箇所に、:collationオプションについての説明を追加しています。


Call block to #redirect_to in controller context (#33735)

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

redirect_toメソッドのoptions引数にProcを指定した場合に、controllerのcontextでProcを実行するよう修正しています。

ドキュメントにその旨説明されており(https://api.rubyonrails.org/classes/ActionController/Redirecting.html#method-i-redirect_to)、説明と挙動を合わせる為。


Merge pull request #33654 from kamipo/fix_numericality_validator_2

activemodel/lib/active_model/validations/numericality.rbの修正です。

NumericalityValidator#validate_eachメソッドでvalueを取得する際に、xx_came_from_user?read_attributeが定義されていなければ、type cast前のvalueを使用するよう修正しています。

Active Recordを使用している場合は問題無いのですが、Active Record以外のサードパーティのライブラリ(Mongoidやactive_attr)ではread_attribute等のメソッドが定義されていない為。


Update the comments for TimeWithZone subtraction (#33721)

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

TimeWithZone#-メソッドのdocの戻り値についての説明を修正しています。


Use the HTTPS protocol for links to Edges Guides [ci skip]

rails guideの修正です。

edgeguides.rubyonrails.org へのリンクをHTTPSに修正しています。


Merge pull request #33689 from ypresto/ar-fix-dirty-in-around

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

around callbacks(e.g. around_create)内でyield実行後にdirty moduleが管理している値が正しくclearされないバグがあったのを修正しています。

rails commit log流し読み(2018/08/27)

2018/08/27分のコミットです。

CHANGELOGへの追加はありませんでした。


Follow up #33523 [ci skip]

rails guideのAction View Form Helpersの修正です。

formの生成処理のexampleにform_forform_tagを使用していたのを、form_withを使用するようInclude form_with in form_helpers rails guide (#33523)で修正されたのですが、本文中の説明が古いままになっていたのを修正、form_withのexampleコードを正しい内容に修正、等を行っています。


Add :namespace option to the api docs of form_with [ci skip]

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

form_withメソッドのdocに:namespaceオプションについての説明を追加しています。

rails commit log流し読み(2018/08/25)

2018/08/25分のコミットです。

CHANGELOGへの追加はありませんでした。


Avoid pg 1.1.0 for now

Gemfileの修正です。

pg gem 1.1.0を使用しないようバージョンロックを追加しています。1.1.0でdeprecateになったメソッドの使い方をしている箇所があり、その影響でテストがエラーになってしまう為。


Format respond_to method as code in doc [ci skip]

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

respond_toメソッドのdoc内、respond_toをコードフォーマットになるよう修正しています。


Add test case to test enum in has_many

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

has_many association + enumが正しく動作する事を確認するテストを追加しています。


Clarify example of the test [ci skip]

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

fixture_file_uploadメソッドのdoc内、postメソッドを使用したexampleで引数の指定方法に誤りがあったのを修正しています。


Remove unused requires

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

使用していないファイルのrequireを削除しています。