2020/05/24分のコミットです。
CHANGELOGにのったコミットは以下の通りです。
- Deprecate aggregations with group by duplicated fields.
- Deprecate duplicated query annotations.
- Default engine
ENGINE=InnoDB
is no longer dumped to make schema more agnostic. - Added delegated type as an alternative to single-table inheritance for representing class hierarchies.
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.rb
、
activerecord/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/DeletePrefix
とPerformance/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
の修正です。
annotate
とoptimizer_hints
が指定されているrelationもor
に指定出来るよう修正しています。