Upgrade to Pro — share decks privately, control downloads, hide ads and more …

computed_modelの紹介 / Introducing computed_model

computed_modelの紹介 / Introducing computed_model

Ruby on RailsではDB上の生データから導出したデータを定義するためにモデルクラスに新たなメソッドを定義することがあります。しか、多数のレコードを効率よく読み出すためにpreloadを使うと、結局生データのありかを指定する必要があり抽象化が阻害されてしまいます。

computed_modelはこの問題を解決するために、モデルクラスでデータの依存関係を記述するDSLを提供します。この仕組みはActiveRecordなど特定のデータソースに依存せず、複数データソースにも対応しているため、特にマイクロサービス化によって分断されてしまったデータの再集約で効果を発揮します。

Masaki Hara

October 10, 2021
Tweet

More Decks by Masaki Hara

Other Decks in Programming

Transcript

  1. ©2021 Wantedly, Inc. class User < ApplicationRecord def short_description current_job.then

    { |c| "#{c.company_name} #{c.position}" } end def current_job jobs.sort { ... }.find { ... } en d end ಈػ Model method 2
  2. ©2021 Wantedly, Inc. class User < ApplicationRecord has_many :jobs end

    users = User.where(...).preload(:jobs).to_ a ಈػ Preload 3
  3. ©2021 Wantedly, Inc. users = User.where(...).preload(:jobs).to_ a users.each do |user

    | sd = user.short_descriptio n .. . end ಈػ Model method + preload 4
  4. ©2021 Wantedly, Inc. ੍໿  "DUJWF3FDPSEʹґଘ͠ͳ͍ w ଞϚΠΫϩαʔϏε͔Βऔಘ͢Δ৘ใ΋͋Δ w ෳ਺ιʔε͔Βͷ৘ใͷऔಘ΋ඞཁ

     ωετͨ͠QSFMPBE  7JFXʹඥ෇͔ͳ͍ w (SBQI2-ͳͲಛఆͷϓϩτίϧʹΑΒͣɺ൚༻తʹ࢖͍͍ͨ 5
  5. ©2021 Wantedly, Inc. class User dependency :current_job computed def short_description

    current_job.then { |c| "#{c.company_name} #{c.position}" } end dependency :jobs computed def current_job jobs.sort { ... }.find { ... } end end ղ๏ .PEFMʹґଘؔ܎Λॻ͘ એݴ͍ͯ͠ͳ͍ґଘؔ܎Λ࢖͏ͱ࣮ߦ࣌ΤϥʔʹͳΔ 6
  6. ©2021 Wantedly, Inc. class User include ComputedModel::Mode l dependency :current_job

    computed def short_description ... en d dependency :jobs computed def current_job ... end end ղ๏ .PEFMʹґଘؔ܎Λॻ͘ %FQFOEFODZ DPNQVUFE͸$PNQVUFE.PEFM.PEFM͔Βར༻Ͱ͖Δ 7
  7. ©2021 Wantedly, Inc. users = User.list(user_ids, [:short_description] ) users.each do

    |user | sd = user.short_descriptio n .. . end ղ๏ ཉ͍͠ϑΟʔϧυΛࢦఆͯ͠ϩʔυ ࢦఆ͍ͯ͠ͳ͍ϑΟʔϧυΛ௚઀࢖͏ͱ࣮ߦ࣌ΤϥʔʹͳΔ 8
  8. ©2021 Wantedly, Inc. class User define_primary_loader :raw_user do |subfields, ids:

    | RawUser.where(id: ids).preload(subfields).map do |raw_user | User.new(raw_user ) end end end ղ๏ σʔλιʔε΋ࣗ෼Ͱॻ͘ ͔ͩΒɺͲΜͳσʔλιʔεʹ΋ద߹͢Δ 9
  9. ©2021 Wantedly, Inc. class User define_primary_loader :raw_user { ... }

    define_loader :books, key: -> { id } do |user_ids, _subfields, ** | BookApi.list(user_id: user_ids).group_by(&:user_id ) end end ղ๏ ෳ਺σʔλιʔε ϚΠΫϩαʔϏε܈͔Β৘ใΛ͔͖ूΊΔͷ΋؆୯ 10
  10. ©2021 Wantedly, Inc. ࣾ಺ͷར༻ྫ  6TFSϞσϧ w Ϣʔβʔͷ৘ใʹؔ৺Λ࣋ͭαʔϏε͸ଟ͍ w ͦͷͨΊɺෳ਺ͷϚΠΫϩαʔϏε͔Β৘ใΛ

    
 ू໿͢Δඞཁ͕͠͹͠͹ੜ͡Δ  ݖݶ؅ཧ w "DUJWF3FDPSEͷϞσϧΛϥοϓͯ͠ɺ 
 ݟ͍͍ͯ৘ใ͚͕ͩϑΟϧλ͞ΕͨϞσϧΛ࡞Δ 11