[STATUS: ONLINE] 当サイトは要約付きのエンジニア向けFeedです。

TechDistill.dev

[DISCLAIMER] 当サイトの要約は正確性を保証しません。気になる記事は必ず原文を確認してください。
cd ..

【要約】【Rails】給湯器のサンプルアプリで学ぶDelegatedType [Qiita_Trend] | Summary by TechDistill

> Source: Qiita_Trend
Execute Primary Source

// Problem

Rails開発者が、共通属性を持ちつつ詳細属性が異なる複数のモデルを設計する際、DB設計とコードの抽象化のトレードオフに直面する問題がある。具体的には以下の課題が挙げられる。


  • STI(単一テーブル継承)を採用した場合、全サブクラスのカラムを1つのテーブルに集約するため、特定の型にしか使われないカラムが大量にNULLとして存在し、テーブルが肥大化する。
  • has_oneによるコンポジションでは、テーブルは分割されるが、親モデルから抽象的に関連を扱えず、N+1問題の回避やコードの記述が複雑になる。

// Approach

著者は、Rails 6.1で導入されたDelegatedTypeを用いて、DBの正規化とモデルの抽象化を両立するアプローチを提案している。具体的な手法は以下の通りである。


  • 親モデルにdelegated_typeを定義し、具体的なサブクラスを抽象的なインターフェースとして扱う。
  • 各サブクラスは、親モデルに対してhas_one :product, as: :heaterのように、ポリモーフィックな関連を定義する。
  • これにより、Product.includes(:heater)といった簡潔な記述で、異なるサブクラスを抽象的に一括ロードできる。

// Result

DelegatedTypeの導入により、DB設計の整合性と開発効率の両面で成果が得られる。具体的には以下の改善が見込まれる。


  • DB設計面では、各サブクラスが自身の属性のみを持つ専用テーブルを持つため、不要なカラムを排除し、スキーマをクリーンに保てる。
  • 実装面では、Product.includes(:heater)のように、具体的な型を意識せずにポリモーフィックな関連を扱えるため、コードが簡潔になり、N+1問題も容易に解決できる。

Senior Engineer Insight

> 実戦におけるスケーラビリティの観点から、本手法は極めて合理的だ。属性の追加が頻繁なドメインにおいて、STIによるテーブル肥大化は運用上の負債となる。DelegatedTypeはDBの正規化を維持しつつ、Railsの強力な抽象化の恩恵を受けられる。ただし、関連の向きが「親が子を持つ」から「子が親を持つ」へ逆転する点には注意が必要だ。設計ミスを防ぐため、touch: truedependent: :destroyを適切に設定し、データの整合性を担保することが運用の鍵となる。

[ RELATED_KERNELS_DETECTED ]

cd ..

> System.About()

TechDistillは、膨大な技術記事から情報の真髄(Kernel)のみを抽出・提示します。