週刊Railsウォッチ(20181029) 特集『肥大化したActiveRecordリファクタリング7つの方法』今ならどうなる?Redis 5のストリーム機能他

こんにちは、hachi8833です。遅ればせながら先週はGitHubの中の皆さまお疲れさまです。 昨日から発生していたGitHub の障害は復旧ました。多大なるご迷惑をおかけしましたこと深くお詫び申し上げます。 — GitHub Japan (@GitHubJapan) October 23, 2018 つっつきボイス:「自分はあの日たまたまGitHubには触ってなかったんでそんなに影響なかったかな」「チームではハマった人もいたみたい」「私はGitHubでリポジトリを追加した後プッシュしたら半日何も出てこなくて、夜リロードしたらやっと出てきました🌙」 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ 「つっつきボイス」はRailsウォッチ公開前ドラフトを社内有志でつっついたときの会話です👄 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください 公開つっつき会のお知らせ おかげさまで公開つっつき会の第4回の参加希望者が初めて6人になりました😂。定員を引き上げましたのでご安心を🙇。 ⚓Rails: 先週の改修(Rails公式ニュースより) 公式の更新情報がなかったので、例によってコミットログから見繕いました。今回はますますドキュメントの更新が多くなっていてpreview-releaseを予感させ、その分改修は小粒な感じです。 ⚓ActiveJobテストヘルパーから返されるジョブインスタンスにdeserializeされた引数を含めるようにした PR: Include deserialized arguments in jobs returned by AJ test helpers by XrXr · Pull Request #34204 · rails/rails # activejob/lib/active_job/test_helper.rb#L615 def instantiate_job(payload) – job = payload[:job].new(*payload[:args]) + args = ActiveJob::Arguments.deserialize(payload[:args]) + job = payload[:job].new(*args) job.scheduled_at = Time.at(payload[:at]) if payload.key?(:at) job.queue_name = payload[:queue] job end つっつきボイス:「ActiveRecordをARと略すのはよくやるけど、ActiveJobはAJ☺️」「Ajaxかと思た」「payloadを加工しないでそのまま渡すようにしたと: 前は通らなかったキーワード引数がこれで通る↓」 # activejob/test/cases/test_helper_test.rb#L477 def test_assert_enqueued_with_returns job = assert_enqueued_with(job: LoggingJob) do – LoggingJob.set(wait_until: 5.minutes.from_now).perform_later(1, 2, 3) + LoggingJob.set(wait_until: 5.minutes.from_now).perform_later(1, 2, 3, keyword: true) end … ⚓IN句の値がboundable?かどうかにかかわらずpre-checkingをlazyにした 元記事: Lazy checking whether or not values in IN clause are boundable by kamipo · Pull Request #34303 · rails/rails #33844以降eager-loadingやpreloadingでidが大量かつ巨大な場合、値がconstructableかどうかというpre-checkで阻止されないようになった。しかしこのpre-checkはクエリ実行時ではなくリレーションのビルド時に型を評価していて、一部のアプリで期待どおり動作しないことがあった。 そこでpre-checkをできる限りlazyにするようにし、リレーションのビルド時に型評価が発生しないようにした。 同PRより大意 # activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb#L13 – def visit_Arel_Nodes_In(*) + def visit_Arel_Nodes_In(o, collector) @preparable = false + if Array === o.right && !o.right.empty? + o.right.delete_if do |bind| + if Arel::Nodes::BindParam === bind && Relation::QueryAttribute === bind.value + !bind.value.boundable? + end + end + end super end つっつきボイス:「boundable?ってタイトルでわからなかったけどメソッド名でした」「oって何だ?😆」「Go言語みたいなあっさりしたローカル変数名ですね☺️」「コードはSQLのINになるパラメータを渡したときの挙動を変更したようだ」 参考: 逆引きSQL構文集 - IN句を用いた副問合せ 「うん、bind if bind.value.boundable?をArrayHandlerからDetermineIfPreparableVisitorに移動して展開のタイミングを後ろにずらしたんですね」「2**63というめちゃでかい値でテストしてる↓⛰」「2の63乗!」 # activerecord/test/cases/bind_parameter_test.rb#L37 def test_too_many_binds bind_params_length = @connection.send(:bind_params_length) – topics = Topic.where(id: (1 .. bind_params_length … Continue reading 週刊Railsウォッチ(20181029) 特集『肥大化したActiveRecordリファクタリング7つの方法』今ならどうなる?Redis 5のストリーム機能他