From a21bcac9e156d8c40fe7c15c62ac71a901091cc5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 30 Nov 2016 15:57:56 +0100 Subject: [PATCH] Further abstract caching for includes --- app/controllers/application_controller.rb | 2 ++ app/models/concerns/cacheable.rb | 15 +++++++++++++++ app/models/notification.rb | 3 ++- app/models/status.rb | 4 +++- 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 app/models/concerns/cacheable.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5243bc446..9722f86b5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -59,6 +59,8 @@ class ApplicationController < ActionController::Base end def cache_collection(raw, klass) + return raw unless klass.respond_to?(:with_includes) + uncached_ids = [] cached_keys_with_value = Rails.cache.read_multi(*raw.map(&:cache_key)) diff --git a/app/models/concerns/cacheable.rb b/app/models/concerns/cacheable.rb new file mode 100644 index 000000000..cd0167048 --- /dev/null +++ b/app/models/concerns/cacheable.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Cacheable + extend ActiveSupport::Concern + + class_methods do + def cache_associated(*associations) + @cache_associated = associations + end + end + + included do + scope :with_includes, -> { includes(@cache_associated) } + end +end diff --git a/app/models/notification.rb b/app/models/notification.rb index c0537397c..b066cd87a 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -2,6 +2,7 @@ class Notification < ApplicationRecord include Paginable + include Cacheable belongs_to :account belongs_to :activity, polymorphic: true @@ -15,7 +16,7 @@ class Notification < ApplicationRecord STATUS_INCLUDES = [:account, :stream_entry, :media_attachments, :tags, mentions: :account, reblog: [:stream_entry, :account, :media_attachments, :tags, mentions: :account]].freeze - scope :with_includes, -> { includes(status: STATUS_INCLUDES, mention: [status: STATUS_INCLUDES], favourite: [:account, status: STATUS_INCLUDES], follow: :account) } + cache_associated status: STATUS_INCLUDES, mention: [status: STATUS_INCLUDES], favourite: [:account, status: STATUS_INCLUDES], follow: :account def activity send(activity_type.downcase) diff --git a/app/models/status.rb b/app/models/status.rb index f9dcd97e4..8f65a3ecc 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -3,6 +3,7 @@ class Status < ApplicationRecord include Paginable include Streamable + include Cacheable belongs_to :account, inverse_of: :statuses @@ -27,7 +28,8 @@ class Status < ApplicationRecord default_scope { order('id desc') } scope :with_counters, -> { select('statuses.*, (select count(r.id) from statuses as r where r.reblog_of_id = statuses.id) as reblogs_count, (select count(f.id) from favourites as f where f.status_id = statuses.id) as favourites_count') } - scope :with_includes, -> { includes(:account, :media_attachments, :tags, :stream_entry, mentions: :account, reblog: [:account, :stream_entry, :tags, :media_attachments, mentions: :account], thread: :account) } + + cache_associated :account, :media_attachments, :tags, :stream_entry, mentions: :account, reblog: [:account, :stream_entry, :tags, :media_attachments, mentions: :account], thread: :account def local? uri.nil?