about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2016-09-08 20:36:01 +0200
committerEugen Rochko <eugen@zeonfederated.com>2016-09-08 20:36:01 +0200
commit85d89b472dff2c3d06801dbd42f91c325d21a434 (patch)
treeb348297bf48c63f906cdcdbc1ff573203afb560a /app
parenta4cc966476852542f445793b60c67ad3682976e5 (diff)
Optimized n+1 queries in accounts Atom and HTML views
Added stack trace for SQL queries in development
Removed badly thought out accounts/lookup API
Diffstat (limited to 'app')
-rw-r--r--app/controllers/accounts_controller.rb17
-rw-r--r--app/controllers/api/accounts/lookup_controller.rb14
-rw-r--r--app/helpers/api/accounts/lookup_helper.rb2
-rw-r--r--app/helpers/application_helper.rb19
-rw-r--r--app/helpers/stream_entries_helper.rb4
-rw-r--r--app/models/status.rb2
-rw-r--r--app/models/stream_entry.rb12
7 files changed, 37 insertions, 33 deletions
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb
index 3c02e0bec..c10a2c680 100644
--- a/app/controllers/accounts_controller.rb
+++ b/app/controllers/accounts_controller.rb
@@ -6,14 +6,21 @@ class AccountsController < ApplicationController
 
   def show
     respond_to do |format|
-      format.html { @statuses = @account.statuses.order('id desc').with_includes.with_counters.paginate(page: params[:page], per_page: 10)}
+      format.html do
+        @statuses   = @account.statuses.order('id desc').with_includes.with_counters.paginate(page: params[:page], per_page: 10)
+
+        if user_signed_in?
+          status_ids  = @statuses.collect { |s| [s.id, s.reblog_of_id] }.flatten.uniq
+          @favourited = Favourite.where(status_id: status_ids).where(account_id: current_user.account_id).map { |f| [f.status_id, true] }.to_h
+          @reblogged  = Status.where(reblog_of_id: status_ids).where(account_id: current_user.account_id).map { |s| [s.reblog_of_id, true] }.to_h
+        else
+          @favourited = {}
+          @reblogged  = {}
+        end
+      end
 
       format.atom do
         @entries = @account.stream_entries.order('id desc').with_includes.paginate_by_max_id(20, params[:max_id] || nil)
-
-        ActiveRecord::Associations::Preloader.new.preload(@entries.select { |a| a.activity_type == 'Status' }, activity: [:mentions, :media_attachments, reblog: :account, thread: :account])
-        ActiveRecord::Associations::Preloader.new.preload(@entries.select { |a| a.activity_type == 'Favourite' }, activity: [:account, :status])
-        ActiveRecord::Associations::Preloader.new.preload(@entries.select { |a| a.activity_type == 'Follow' }, activity: :target_account)
       end
     end
   end
diff --git a/app/controllers/api/accounts/lookup_controller.rb b/app/controllers/api/accounts/lookup_controller.rb
deleted file mode 100644
index 319401a2e..000000000
--- a/app/controllers/api/accounts/lookup_controller.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class Api::Accounts::LookupController < ApiController
-  before_action :doorkeeper_authorize!
-  respond_to    :json
-
-  def index
-    @accounts = Account.where(domain: nil).where(username: lookup_params)
-  end
-
-  private
-
-  def lookup_params
-    (params[:usernames] || '').split(',').map(&:strip)
-  end
-end
diff --git a/app/helpers/api/accounts/lookup_helper.rb b/app/helpers/api/accounts/lookup_helper.rb
deleted file mode 100644
index 5caf0e28c..000000000
--- a/app/helpers/api/accounts/lookup_helper.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-module Api::Accounts::LookupHelper
-end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index e0105ee54..e43875544 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -22,23 +22,26 @@ module ApplicationHelper
 
   def account_from_mentions(search_string, mentions)
     mentions.each { |x| return x.account if x.account.acct.eql?(search_string) }
+    nil
 
     # If that was unsuccessful, try fetching user from db separately
     # But this shouldn't ever happen if the mentions were created correctly!
-    username, domain = search_string.split('@')
+    # username, domain = search_string.split('@')
 
-    if domain == Rails.configuration.x.local_domain
-      account = Account.find_local(username)
-    else
-      account = Account.find_remote(username, domain)
-    end
+    # if domain == Rails.configuration.x.local_domain
+    #   account = Account.find_local(username)
+    # else
+    #   account = Account.find_remote(username, domain)
+    # end
 
-    account
+    # account
   end
 
   def linkify(status)
     auto_link(HTMLEntities.new.encode(status.text), link: :urls, html: { rel: 'nofollow noopener' }).gsub(Account::MENTION_RE) do |m|
-      if account = account_from_mentions(Account::MENTION_RE.match(m)[1], status.mentions)
+      account = account_from_mentions(Account::MENTION_RE.match(m)[1], status.mentions)
+
+      unless account.nil?
         "#{m.split('@').first}<a href=\"#{url_for_target(account)}\" class=\"mention\">@<span>#{account.acct}</span></a>"
       else
         m
diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb
index a29014d1b..ce77206ea 100644
--- a/app/helpers/stream_entries_helper.rb
+++ b/app/helpers/stream_entries_helper.rb
@@ -21,11 +21,11 @@ module StreamEntriesHelper
   end
 
   def reblogged_by_me_class(status)
-    user_signed_in? && current_user.account.reblogged?(status) ? 'reblogged' : ''
+    user_signed_in? && @reblogged.has_key?(status.id) ? 'reblogged' : ''
   end
 
   def favourited_by_me_class(status)
-    user_signed_in? && current_user.account.favourited?(status) ? 'favourited' : ''
+    user_signed_in? && @favourited.has_key?(status.id) ? 'favourited' : ''
   end
 
   def proper_status(status)
diff --git a/app/models/status.rb b/app/models/status.rb
index df9eceaff..12c58733c 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -18,7 +18,7 @@ class Status < ApplicationRecord
   validates :text, presence: true, if: Proc.new { |s| s.local? && !s.reblog? }
 
   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, :mentions, :media_attachments, :stream_entry, reblog: [:account, :mentions], thread: :account) }
+  scope :with_includes, -> { includes(:account, :media_attachments, :stream_entry, mentions: :account, reblog: [:account, mentions: :account], thread: :account) }
 
   def local?
     self.uri.nil?
diff --git a/app/models/stream_entry.rb b/app/models/stream_entry.rb
index 165f62f20..f33295796 100644
--- a/app/models/stream_entry.rb
+++ b/app/models/stream_entry.rb
@@ -4,9 +4,15 @@ class StreamEntry < ApplicationRecord
   belongs_to :account, inverse_of: :stream_entries
   belongs_to :activity, polymorphic: true
 
+  belongs_to :status,    foreign_type: 'Status',    foreign_key: 'activity_id'
+  belongs_to :follow,    foreign_type: 'Follow',    foreign_key: 'activity_id'
+  belongs_to :favourite, foreign_type: 'Favourite', foreign_key: 'activity_id'
+
   validates :account, :activity, presence: true
 
-  scope :with_includes, -> { includes(:activity) }
+  STATUS_INCLUDES = [:account, :stream_entry, :media_attachments, mentions: :account, reblog: [:stream_entry, :account, mentions: :account], thread: [:stream_entry, :account]]
+
+  scope :with_includes, -> { includes(:account, status: STATUS_INCLUDES, favourite: [:account, :stream_entry, status: STATUS_INCLUDES], follow: [:target_account, :stream_entry]) }
 
   def object_type
     orphaned? ? :activity : (targeted? ? :activity : self.activity.object_type)
@@ -44,6 +50,10 @@ class StreamEntry < ApplicationRecord
     self.activity.respond_to?(:mentions) ? self.activity.mentions.map { |x| x.account } : []
   end
 
+  def activity
+    self.send(self.activity_type.downcase.to_sym)
+  end
+
   private
 
   def orphaned?