なるようになるブログ

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

rails commit log流し読み(2020/05/24)

2020/05/24分のコミットです。

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

activerecord/CHANGELOG.md


Deduplicate same clauses in merge

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

mergeで同じ句を排除するよう修正しています。


Merge pull request #39390 from kamipo/fix_has_many_through_with_join_scope

Active Recordの修正です。

through associationでsource / through scopeをjoinした際に、不正なSQLが生成されてしまうバグがあったのを修正していmさう。


Pass over the "Calling the Mailer" AM guide [ci skip] (#39402)

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

guide全体の言い回し、グラマーの修正を行っています。


Deprecate aggregations with group by duplicated fields

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

aggregations + groupした場合に、同じfieldsが複数生成されてしまう事がある、という挙動がdeprecateになりました。

accounts = Account.group(:firm_id)
accounts.merge(accounts.where.not(credit_limit: nil)).sum(:credit_limit)
# => {
#   [1, 1] => 50,
#   [2, 2] => 60
# }

元々上記のようになっていたのが、

accounts = Account.group(:firm_id)
accounts.merge(accounts.where.not(credit_limit: nil)).sum(:credit_limit)
# => {
#   1 => 50,
#   2 => 60
# }

になります。同じfieldsが複数含まれるのは元々意図的ではなかった筈、かつ、複数含む必要も無いため。また、annotateにも同様の問題があった為、こちらも同様にdeprecateになっています。


Remove redundant blank? check and compact_blank! for joins_values

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

joins_valuesから不要なblank?チェックとcompact_blank!の呼び出しを削除しています。


Take primay_key in count in ActiveRecord::SignedId (#39404)

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

ActiveRecord::SignedIdでデータ取得時のカラム名id固定になっていたのを、primay_keyメソッド経由でカラム名を取得するよう修正しています。


Copy options before delegating in with_options

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

with_options + nested routesを指定した際に、routesが正しく生成されないバグがあったのを修正しています。


Add delegated type to Active Record (#39341)

Active Recordの修正です。

クラス階層を表す為の処理として、delegated typeという機能をActive Recordに追加しています。

Railsにはクラス階層の為の仕組みとしてSTIがあるのですが、STIだと子クラスに追加したいcolumnを全て親クラスに追加する必要がある(それが他の子クラスでは不要だとしても)、という問題がありました。

delegated typeでは親クラスと子クラスでそれぞれ別のテーブルを保持し、親に共通で使う処理とカラムを保持、子ではの子でのみ必要なカラムと処理を持てるようにしてその問題を解決しています。

例。

# Schema: entries[ id, account_id, creator_id, created_at, updated_at, entryable_type, entryable_id ]
class Entry < ApplicationRecord
  delegated_type :entryable, types: %w[ Message Comment ], dependent: :destroy
end

# Schema: messages[ id, subject ]
class Message < ApplicationRecord
end

# Schema: comments[ id, content ]
class Comment < ApplicationRecord
end

親のEntryクラスで、delegated_typeメソッドを使用して子クラスの定義を行います。関連付けにはポリモーフィックが使用されており、親クラスにはxxx_id及びxxx_typeカラムが必要です。親クラスには子クラスを取得する為のメソッドを定義され、それらのメソッドを使用し、子クラスの処理を呼び出せるようになっています。

Entry.messages
#  SELECT "entries".* FROM "entries" WHERE "entries"."entryable_type" = ? LIMIT ?  [["entryable_type", "Message"], ["LIMIT", 11]]
# => #<ActiveRecord::Relation [#<Entry id: 1, entryable_type: "Message", entryable_id: 1, created_at: "2020-05-24 05:42:38.420043000 +0000", updated_at: "2020-05-24 05:42:38.420043000 +0000">]>

Entry.first.message_id
Entry.first.message.subject

使い方等の詳細は、API Doc ActiveRecord::DelegatedType参照。


Default engine ENGINE=InnoDB is no longer dumped to make schema more agnostic

Active Recordの修正です。

schemaファイルにengineの値を出力しないよう修正しています。

元々はlarge keyでutf8mb4を使用する為に出力していました。しかし現在Active RecordでサポートしているMySQLではこの情報が不要になった(デフォルトのrow formatがDYNAMICになった)為、出力しないよう修正しています。


Separate primary key column options from table options

Active Recordの修正です。

primary key column optionsをtable optionsから分離しています。columnとtableで同じ名前のオプションを扱えるようにする為。


Do not use object_id on Active Record object directly

Active Recordの修正です。

Active Record objectのobject_idを使用していた箇所を修正しています。

object_idという名前のattributeを定義する事が出来てしまう、かつ、その場合に想定外の挙動になってしまうのを避ける為。


Update rubocop-performance gem and enable Performance/DeletePrefix and Performance/DeleteSuffix cops

rubocop-performance gemのバージョンを1.6.0に更新、及び、Performance/DeletePrefixPerformance/DeleteSuffix copを有効化するよう修正しています。


"Neither relation may have a #limit, #offset, or #distinct set." is not true

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

orメソッドのdocに、orに指定するrelationには#limit#offset、または#distinctが指定されてある必要がある旨説明があったのを削除しています。現状その制限は無い為。


[skip-ci] Fix delegated_type examples

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

delegated_typeメソッドのdoc内のレコード作成のexampleの内容に誤りがあったのを修正しています。


Allow relations with different SQL comments in or

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

annotateoptimizer_hintsが指定されているrelationもorに指定出来るよう修正しています。