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

森羅万象に「いいね」するためのデータ構造

 森羅万象に「いいね」するためのデータ構造

Kaigi on Rails 2022 にて『森羅万象に「いいね」するためのデータ構造』の発表をしました。
https://kaigionrails.org/2022/talks/pndcat/

===概要===

サービス開発をしていると「いいね」の実装に対面することは多いでしょう。例えば EC サービスの場合、商品へのいいね、クチコミへのいいね、ブランドへのいいねなど、いろいろな対象に「いいね」をするケースが考えられます。さらには、ログインユーザーの「いいね」と、非ログインユーザーの「いいね」を作ることもあるかもしれません。

しかし、あらゆるものに「いいね」できるシステムを作るのは容易ならざることです。普通に実装するだけでは関連するコードは肥大化し、データベースのテーブルもどんどん増えていくばかりです。

似ているけど少し違う「いいね」を実装するにあたって、失敗してしまったデータ設計、そこにあった悩みや苦しみ、それらを解決していくリファクタリングの道すじを説明します。

なっちゃん

October 24, 2022
Tweet

More Decks by なっちゃん

Other Decks in Programming

Transcript

  1. • ͳͲ΍· ͳͭ͜ / @pndcat • ΫοΫύουגࣜձࣾ 2017೥ʙ • 2ຊ໨ͷτʔΫͷ

    @osyoyu ͱҰॹʹಇ͍͍ͯ·͢ • ࡢ೥ @asonas ͕ൃද͍ͯͨ͠αʔϏεͷ։ൃͷ࿩ • ήʔϜΛͨ͠Γɺਪ͠׆ಈΛ͍ͯ͠·͢ 2 ࣗݾ঺հ
  2. • ͍͍Ͷͷର৅ ◦ ঎඼ ◦ τϐοΫ • ͍͍ͶΛ͢Δଆ ◦ ϩάΠϯϢʔβʔͷ͍͍Ͷ

    ◦ ϩάΠϯ͍ͯ͠ͳ͍Ϣʔβʔͷ͍͍Ͷʢಗ໊͍͍Ͷʣ • ʮ͍͍Ͷʯͷର৅͸ࠓޙ૿͑Δ͔΋͠Εͳ͍ 12 ٻΊΒΕ͍ͯΔʮ͍͍Ͷʯػೳ
  3. • ର৅ผɺ͍͍Ͷɾಗ໊͍͍Ͷ͝ͱʹςʔϒϧΛ࡞Δ ◦ product_likes ◦ product_anonymous_likes ◦ topic_likes ◦ topic_anonymous_likes

    • ϙϦϞʔϑΟοΫؔ࿈ • STI 14 ʮ͍͍Ͷʯͷσʔλߏ଄ ։ൃ͕ਐΉͱ࢓༷ɾৼΔ෣͍ɾڍಈ͕มߋ͞Ε͏Δ มߋʹ଱͑ΒΕΔΑ͏ʹγϯϓϧͳσʔλߏ଄ʹ͢Δ → ର৅ผɺ͍͍Ͷɾಗ໊͍͍Ͷ͝ͱʹςʔϒϧΛ࡞Δ
  4. 15 ॳظͷςʔϒϧߏ଄ product_likes product_id user_id product_anonymous_likes product_id like_identifier products id

    name ộ User ID (number) User ID ͕ͳ͍ͷͰϥϯμϜͳจࣈྻΛੜ੒ (string)
  5. 16 ॳظͷςʔϒϧߏ଄ product_likes product_id user_id product_anonymous_likes product_id like_identifier products id

    name ộ User ID (number) User ID ͕ͳ͍ͷͰϥϯμϜͳจࣈྻΛੜ੒ (string) ҟͳΔσʔλΛಉ͡ΧϥϜʹೖΕΔͷ͸ෳࡶ ͍͍Ͷͱɺಗ໊͍͍Ͷ͸ผͷςʔϒϧͰఆٛ
  6. • ʮ͍͍Ͷʯͷର৅͕૿͑ΔͨͼʹɺςʔϒϧɾϞσϧɾ ίϯτϩʔϥʔΛຖճ௥Ճ͢ΔͷͰͭΒ͍ ◦ ঎඼ɺτϐοΫɺΫνίϛɺίϝϯτ (8ςʔϒϧ) 17 ࣦഊͨ͠ͱ͜Ζ product_likes product_id

    user_id product_anonymous_likes product_id like_identifier topic_likes topic_id user_id kuchikomi_likes kuchikomi_id user_id comment_likes comment_id user_id topic_anonymous_likes topic_id like_identifier comment_anonymous_likes comment_id like_identifier kuchikomi_anonymous_likes kuchikomi_id like_identifier
  7. • ϙϦϞʔϑΟοΫؔ࿈: 1ͭͷϞσϧΛෳ਺ͷϞσϧʹؔ࿈͚ͮΔ ◦ Like ϞσϧΛ࡞Δ ◦ ڞ௨ͷৼΔ෣͍Λ͢Δ৔߹͸ڧྗͳσʔλߏ଄ ▪ if

    จΛॻ͘ͱഁ୼͢Δ • STI: ܧঝΛ࢖ͬͯςʔϒϧΛ1ͭʹ͢Δ ◦ ProductLike ͸ Like Λܧঝ͢Δ ◦ ֤ʮ͍͍ͶʯΫϥεͰৼΔ෣͍Λগ͠ม͑Δ͜ͱ͕Ͱ͖Δ ▪ ࣗ༝౓্͕͕ΔͷͰෛ࠴͕ੜ·ΕΔՄೳੑ͕ߴ͍ 21 ৽͍͠ʮ͍͍Ͷʯͷσʔλߏ଄ͷީิ
  8. • ϙϦϞʔϑΟοΫؔ࿈: 1ͭͷϞσϧΛෳ਺ͷϞσϧʹؔ࿈͚ͮΔ ◦ Like ϞσϧΛ࡞Δ ◦ ڞ௨ͷৼΔ෣͍Λ͢Δ৔߹͸ڧྗͳσʔλߏ଄ ▪ if

    จΛॻ͘ͱഁ୼͢Δ • STI: ܧঝΛ࢖ͬͯςʔϒϧΛ1ͭʹ͢Δ ◦ ProductLike ͸ Like Λܧঝ͢Δ ◦ ֤ʮ͍͍ͶʯΫϥεͰৼΔ෣͍Λগ͠ม͑Δ͜ͱ͕Ͱ͖Δ ▪ ࣗ༝౓্͕͕ΔͷͰෛ࠴͕ੜ·ΕΔՄೳੑ͕ߴ͍ 22 ৽͍͠ʮ͍͍Ͷʯͷσʔλߏ଄ͷީิ • ʮ͍͍Ͷʯ͸ɺڞ௨ͷৼΔ෣͍ͰදݱͰ͖Δ • if จΛઈରʹॻ͔ͳ͍ͱ͍͏ڧ͍ҙࢤͰϙϦ ϞʔϑΟοΫؔ࿈ʹ͢Δ
  9. 24 ৽͍͠σʔλߏ଄: likes (Like) product_likes product_id user_id product_anonymous_likes product_id like_identifier

    topic_likes topic_id user_id topic_anonymous_likes topic_id like_identifier likes likable_id likable_type user_id anonymous_likes likable_id likable_type like_identifier • likes ͱ anonymous_likes ͷ2छྨʹ·ͱΊΔ ◦ user_id ͱ like_identifier ͸ҟͳΔσʔλͷͨΊɺಉ͡ςʔϒϧʹ͸͠ ͳ͍
  10. • create ϝιουͷத਎͸ Likable module ʹ • set_likable Ͱ likable

    Λࢦఆ͢Δ ◦ likable =ʮ͍͍Ͷʯ͞ΕΔର৅ͷ͜ͱ (ྫ: product) 36 ֤ LikesController ͕؆ܿʹʂ Products::LikesController Topics::LikesController
  11. 38