1. tanaken on Rails
  2. #003: ActiveRecord::Delegate..
2024-01-20 17:33

#003: ActiveRecord::DelegatedType

https://scrapbox.io/tanaken0515/A_class_method_to_introspect_delegated_types,_schema_dump_configuration_via_DATABASE_URL,_etc

00:07
こんにちは、tanaken on Railsです。
2024年1月20日の17時です。
第3回のtanaken on Rails始めます。
今週のThis Week in Railsは、紹介されているプレリクエストは1,2,3,4つでございました。
先週までと比べてちょっと少ないですね。
多分これ記事を書く人によっても、書き出すプレリクエストの数、きっと違うんだろうなと思うんですけど。
今回は、その中で1つだけピックアップしてお話ししようと思います。
というのも、これの準備に知らないことが多くてですね、いろいろ時間かかっちゃって、
あんまり時間かけすぎても良くないなと、継続していく意味で良くないなと思ったので、
30分かそこらで準備できる量を準備して、30分ぐらいでしゃべるっていうので、
やっていけたら良いんじゃないかなとなんとなく思っております。
今日は準備に30分以上全然かけて、カフェでゆっくり準備したんですけど、
ということでやっていきたいと思います。
今回ピックアップしたプレリクエストが、
Define a Class Method to Introspect Valid Delegatable Types So They Canというタイトルですね。
何かというと、アクティブレコードに関する修正です。
アクティブレコードデリゲイテッドタイプにクラスメソッドとして、
ロールアンダースコアタイプスっていうクラスメソッドを実装しているよという感じですね。
前提としてデリゲイテッドタイプって何ですかという話をしておきます。
api.rubyonrails.orgのAPIドキュメントによると、
デリゲイテッドタイプメソッドは第1引数がロール、第2引数がキーワード引数でタイプ数、
第3引数以降がオプションズという形でいくつかオプションを渡せるよという感じになってますね。
03:02
アクティブレコードを継承したモデルクラスっていうんですかね。
RailsアプリケーションでDBとつながっているクラスですね。
そいつでデリゲイテッドタイプっていうのを定義して、
ロールを渡してどのタイプですよっていうのを渡すというような使い方をすると。
このデリゲイテッドタイプって何なんですかというのを、
求めてくださっているZenDevの記事というのかな、これは。
ブックか、ウェブ上の本。
ZenDevで公開されている本があったんで、その中の一つの章ですかね。
第6章、Railsの練習帳っていう意外さんがまとめてくださっているZenDevの本のチャプター6っていうところに、
アクティブレコードデリゲイテッドタイプというのがあるんで、
それがすごく分かりやすかったんで皆さんぜひ読んでみてくださいと。
そこに書かれていることを紹介すると、
複数のモデルのオブジェクト、複数テーブルのレコードを統一的に使いたいケースがあります。
例えば、コメントモデルとメッセージモデルのレコード群を足し合わせたものから最新レコード3つを取得したいようなケースです。
Rails 6.1で導入されたデリゲイテッドタイプはこのような状況で使えますと書いてあります。
非常に分かりやすいですね。
複数のモデルがある別々のテーブルで記録されているレコードをまとめて3つ取りたいみたいなケースで使えるよと。
コメントモデルというのとメッセージモデルというのが仮にあるとしましょうと。
これらを統一的に扱うクラスとしてエントリーモデルというものがあるとしましょうと。
エントリーモデルでデリゲイテッドタイプを使って実装ができますよと。
今回の例だとコメントモデルとメッセージモデルから最新のレコード3つ取りたいというときに、
普通のモデルで最新のレコード3つ取ってくるような感じで、
今回はエントリーモデルからentry.last3とかという感じで最新の3つを持ってくるみたいなことができますよと。
どういうふうに実装するんじゃないみたいな話がこのZenDevの第6章のところに書いてあるので、
06:02
すごく分かりやすいのでぜひ読んでみてくださいと。
ついでにというかその例に合わせてもうちょっと説明しますね。
例に合わせてデリゲイテッドタイプをどういうふうに使うのかというと、
エントリーモデルクラスエントリーの中にデリゲイテッドタイプっていうのを書いて、
ここに第一引数のロール、今回はエントリーアブル、
エントリーできるものみたいな概念でエントリーアブルというロールを定義しますと。
カンマでタイプ数、第二引数、キーワード引数ですね。
としてのタイプ数でタイプ数にメッセージとコメントっていうクラス名、モデル名かを文字列の配列、
メッセージという文字列とコメントという文字列をそれぞれ一つずつ要素に持つ、
一つずつ要素に、合わせて二つの要素を持つ配列という形でタイプ数、
書き括弧メッセージ、カンマ、コメント、書き括弧みたいな感じでタイプ数を定義するという感じですね。
そうするとエントリーのインスタンスを作ったときに、
エントリー.エントリーアブルでメッセージモデルのインスタンスあるいはコメントモデルのインスタンスが引けるというか取得できるよというような感じでございますね。
ここまでがデリゲイティッドタイプって何なんですかという話ですね。
今回のプルリクエスト、今回ビッグアップしたプルリクエストで何ができるようになったかというと、
デリゲイティッドタイプに指定したタイプ、
さっきの例だとメッセージとかコメントというクラスがどういうタイプが指定されているのかというのを取得するメソッドが今までなかったみたいなんですよね。
デリゲイティッドタイプに指定されているクラス名、クラスが何なのかというのを知りたいというユースケースがあるみたいです。
プルリクエストを見たんですけど、僕はあんまりまだしっくりきてなくて、
プルリクエストのコメントでは、
ストロングパラメータを指定して、
例えばレールズでコントローラーにパラメータを渡すときにストロングパラメータを使うと思うんですけど、
09:07
そのときにどのクラス、デリゲイティッドタイプに渡ってくるインスタンスがどのクラスなのかというのが、
分からないと困る、どのクラスになりうるのかが分からないと困ることがあるみたいなことなんかなと思ってます。
一応プルリクにはストロングパラメータを使うときにうんぬんかんぬんみたいなことが書いてあるんですけど、
何が何に困っているのかはあんまり分からなかったんですけど、
デリゲイティッドタイプに指定されている取りうるクラスっていうのが、
外から分かったほうがいいよということです。
今回の実装では、
例えばさっきの例、エントリーというモデルがあって、
そこからコメントモデルとメッセージモデルを統合的に扱えるよみたいな話だったんですけど、
エントリーアブルアンダースコアタイプスっていうのをクラスメソッドで勝手に定義されるようになっていて、
エントリーアブルタイプスで配列でメッセージ、カンマ、コメントっていうのが返ってくるようになったと。
なんでこのエントリーアブルっていうロールがどのインスタンスになり得るのか、
メッセージのインスタンスかコメントのインスタンスかのどっちかですよっていうのが、
このクラスメソッドを使うと分かるようになったよという感じですね。
これが実装されましたよという話でございました。
プレリクエスト見てたら、ドキュメントにレールズのレールズガイドのところで、
今回の実装に応じてレールズガイドのマークダウン自体もレールズのリポジタリーで管理されているので、
そこにも差分があって、今回追加されたクラスメソッドについて書かれてたんですけど、
そのドキュメントにミスがあって、クラスメソッドなのにモデル名、シャープ、メソッド名っていう、
インスタンスメソッドを呼び出すときに使う記法が使われてたんで、
エントリードット、モデル名ドット、クラスメソッドっていう感じにした方がいいよねっていうので、
12:06
そのプレリクエストのコメントにもそういうコメントがあったんで、
プレリクエスト探したらまだそのドキュメントの修正のプレリクエストなかったので、
ちょっと試しにと思ってプレリクエストを僕は出してみました。
本当に一文字の修正、シャープをドットにするだけなんですけど、
ちょっと出してみたんで、マジされたらいいなっていう感じです。
というところですね、今回はデリゲイテッドタイプについて調べて、
デリゲイテッドタイプにクラスメソッドが増えたよっていうのを紹介しました。
全然時間余ったな、10分、12分くらいか。
その他3つについては詳しく調べてないんですけど、
3つざっくり説明すると、
データベースURLっていう環境変数か、
スキーマダンプとかクエリキャッシュ、レプリカみたいなやつが、
データベースURLを介して有効にできるようになったっていうことらしいです。
もともとはデータベースURLは、
文字列としてデータベースのURLを指定するか、
フォルスとかを渡せるとかだったんだっけな、
すごいふんわり喋ってますが、
とかだったんだけど、
いいや、ちょっと適当に喋るのやめとこう。
あんまり喋ってないんでこれ。
データベースURLに関する修正、便利になったよっていう話っぽいですね。
その他の2つもいいか。
その他の2つは一応、
IPアドレスのモデルに関するアクティブサポートの修正、
IPアドレスモデルの修正が入ってますっていうのと、
あとは、これはなんだ、
レイルズのロードパス、デフォルトロードパスに関しての修正がありますっていう感じかな。
15:09
みたいな感じですね、ということでございました。
よし、今週はですね、デリゲイテッドタイプについて学べてよかったなと。
デリゲイテッドタイプ自体は僕同じような設計で、
デリゲイテッドタイプと、めっちゃ噛むんだよなこれ。
デリゲイテッドタイプを使わずに実装して業務で使ってました。
自分でこれでいこうっていう、この設計でいこうっていうのでやってて、
当時まだレイルズ6.0だったんですよね、現場で使っているのが。
というのもあって、デリゲイテッドタイプなかったし、
というかデリゲイテッドタイプについてあんまり知らなかったんで、
調べてもなかったし、
自分の思いつくアイデアでこれでいこうっていうので、
実装した処理があるんですけど、
当時もしデリゲイテッドタイプのこと知ってて、
レイルズ6.1以上のやつ使ってたら、
デリゲイテッドタイプ使ってたかもなと思って、
勉強になりましたという感じでございました。
この井上がさんのレイルズの練習帳が非常にすごく分かりやすく丁寧に書かれてるんで、
これをざーっと読んでいくだけでも、
とても学びがありそうだということを感じました。
なので、これも気を見て読んでいきたいなと思っております。
タネケンオンレイルズは一応、
This Week in Railsを読むというのを宣言してやってますが、
途中でチューニングをしてもいいかもという気持ちになってる。
毎週これを読むでも、レイルズの練習帳を読むでもいいかもとか思っております。
そんな感じで終わります。
今回はちょっと早いですが、終わりにしようと思います。
バイバイ。
17:33

コメント

スクロール