$30 off During Our Annual Pro Sale. View Details »

pixivコミックで作品が公開されるってどういうこと?

imadoki
October 05, 2023

 pixivコミックで作品が公開されるってどういうこと?

PIXIV MEETUP2023のLTで発表した際の資料です

imadoki

October 05, 2023
Tweet

More Decks by imadoki

Other Decks in Programming

Transcript

  1. pixiv Inc.
    pixivコミックで作品が公開
    されるってどういうこと?
    @ikumin

    View Slide

  2. Profile
    ikumin
    エンジニア
    2016年入社
    コミック事業部 pixivコミック部
    業務では主にバックエンドを担当し
    ていてRailsを書いています

    View Slide

  3. ● 2012年から始まったマンガ
    サービス
    ● ブラウザ/Android/iOS
    ● 商業作品の連載
    ● 電子書籍の販売
    ● pixivに投稿された作品の閲覧

    View Slide

  4. ● 期間中、無料で何度も読める
    ● 購入すると読める
    連載エピソードの形態

    View Slide

  5. エピソードの公開設定

    View Slide

  6. 基本のデータ

    View Slide

  7. エピソードの公開設定
    ● 公開期間
    ● 種類
    ● (種類によっては)価格

    View Slide

  8. エピソードの公開設定
    # 公開設定
    class PublishingSetting < ApplicationRecord
    ## typeによってどの公開設定化を判別する
    def free?
    type == 'PublishingSetting::Free'
    end
    def sell?
    type == 'PublishingSetting::Sell'
    end
    end

    View Slide

  9. 全話開放キャンペーン

    View Slide

  10. 公開中のエピソードを取得するには
    ● 各種公開フラグがONかどうか?
    ● 期間内の公開設定はあるか?
    ● 全話開放キャンペーン対象かどうか?
    を確認する必要がある

    View Slide

  11. 普通にやってみる
    SELECT `stories`.*
    FROM `stories`
    INNER JOIN `works` `work` ON `work`.`id` = `stories`.`work_id`
    INNER JOIN `magazines` `magazine` ON `magazine`.`id` = `work`.`magazine_id`
    INNER JOIN `publish_all_story_campaign_works` ON
    `publish_all_story_campaign_works`.`work_id` = `work`.`id`
    INNER JOIN `publishing_settings` ON `publishing_settings`.`story_id` =
    `stories`.`id`
    WHERE
    `work`.`is_public` = 1
    AND `magazine`.`is_public` = 1
    AND (
    (`publishing_settings`.`start_at` <= :now)
    AND (`publishing_settings`.`finish_at` < :now OR
    `publishing_settings`.`finish_at` IS NULL)
    OR `publish_all_story_campaigns`.`approved` = 1
    )

    View Slide

  12. 他にも…
    ● レーティングの問題でアプリでは表示できない作品がある
    ● 販売中のエピソードをは購入しなければ読めない
    ● 公開中の作品の最新話を取得したい
    ● 最新話の公開日順に作品を並べ替えたい

    View Slide

  13. ● 公開中のエピソードへの関連と
    最新話の公開日を持つキャッ
    シュ代わりのテーブルを用意
    ● 毎日12時に更新
    キャッシュテーブルの用意

    View Slide

  14. ● 一括で取得した情報をモデルのインスタンスに紐づけて
    くれるgem
    ● https://github.com/walf443/bulk_loader
    BulkLoaderの利用

    View Slide

  15. 購入情報を一括で取得する
    class Story < ApplicationRecord
    #...
    bulk_loader, :purchased? do |ids, user_id|
    next {} if user_id.nil?
    # APIで購入の有無を問い合わせ
    purchased_story_ids =
    Store::App::OrderedEpisodes.get(user_id, ids)
    # {id => purchased?} という形式のHashに変換
    ids.index_with {|id| purchased_story_ids.include?(id) }
    end
    end

    View Slide

  16. 購入情報を一括で取得する
    # ログインユーザーがstoriesを購入しているかどうかを調べる
    Story.bulk_loader.load(:purchased?, stories, current_user)
    stories.each do |story|
    story.purchased? # bulk_loaderでAPIから取得したエピソードごとの購入
    有無を引ける
    end

    View Slide

  17. ● エピソードが購入済みか
    ● エピソードが無料公開中か
    ● エピソードが販売中か
    ● 作品が全話開放キャンペーン中か
    これを利用して

    View Slide

  18. まとめ
    ● 複雑な要件に対応するため、いろんなところに公開に関
    わるデータが散らばっている
    ● 複数のテーブルに絡んだ条件をキャッシュして緩和
    ● BulkLoaderを使ってデータの取得を簡便化

    View Slide

  19. ご清聴ありがとうござい
    ました!

    View Slide