about summary refs log tree commit diff
path: root/app/policies
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2018-05-03 10:41:58 +0200
committerGitHub <noreply@github.com>2018-05-03 10:41:58 +0200
commita5293fdf619b0be32a420c36a73e7ecfbe6d27cd (patch)
tree88dca473e89c1b2201c12e0a8a9d495a338f8712 /app/policies
parenta3d84e705a6e19ebbc240604de62c3ef8531ddf9 (diff)
Fix n+1 queries in StatusThreadingConcern (#7321)
Diffstat (limited to 'app/policies')
-rw-r--r--app/policies/status_policy.rb44
1 files changed, 39 insertions, 5 deletions
diff --git a/app/policies/status_policy.rb b/app/policies/status_policy.rb
index 4145d7e9c..6addc8a8a 100644
--- a/app/policies/status_policy.rb
+++ b/app/policies/status_policy.rb
@@ -1,26 +1,32 @@
 # frozen_string_literal: true
 
 class StatusPolicy < ApplicationPolicy
+  def initialize(current_account, record, preloaded_relations = {})
+    super(current_account, record)
+
+    @preloaded_relations = preloaded_relations
+  end
+
   def index?
     staff?
   end
 
   def show?
     if direct?
-      owned? || record.mentions.where(account: current_account).exists?
+      owned? || mention_exists?
     elsif private?
-      owned? || current_account&.following?(author) || record.mentions.where(account: current_account).exists?
+      owned? || following_author? || mention_exists?
     else
-      current_account.nil? || !author.blocking?(current_account)
+      current_account.nil? || !author_blocking?
     end
   end
 
   def reblog?
-    !direct? && (!private? || owned?) && show? && !current_account&.blocking?(author)
+    !direct? && (!private? || owned?) && show? && !blocking_author?
   end
 
   def favourite?
-    show? && !current_account&.blocking?(author)
+    show? && !blocking_author?
   end
 
   def destroy?
@@ -47,6 +53,34 @@ class StatusPolicy < ApplicationPolicy
     record.private_visibility?
   end
 
+  def mention_exists?
+    return false if current_account.nil?
+
+    if record.mentions.loaded?
+      record.mentions.any? { |mention| mention.account_id == current_account.id }
+    else
+      record.mentions.where(account: current_account).exists?
+    end
+  end
+
+  def blocking_author?
+    return false if current_account.nil?
+
+    @preloaded_relations[:blocking] ? @preloaded_relations[:blocking][author.id] : current_account.blocking?(author)
+  end
+
+  def author_blocking?
+    return false if current_account.nil?
+
+    @preloaded_relations[:blocked_by] ? @preloaded_relations[:blocked_by][author.id] : author.blocking?(current_account)
+  end
+
+  def following_author?
+    return false if current_account.nil?
+
+    @preloaded_relations[:following] ? @preloaded_relations[:following][author.id] : current_account.following?(author)
+  end
+
   def author
     record.account
   end