about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTakeshi Umeda <noel.yoshiba@gmail.com>2020-09-23 23:01:54 +0900
committerGitHub <noreply@github.com>2020-09-23 16:01:54 +0200
commitb655a7f88f653e143d85e1d01bfedde42dc6d9e4 (patch)
treef2f5400265c66eaa7ed07221b23b9df8e48a5e2a
parente39d97f7008499bbf91bb0fb3ae2f794c50f40fc (diff)
Fix a slow query for TagFeed (#14861)
* Fix a slow query for TagFeed

* rename tags to tag_ids
-rw-r--r--app/models/status.rb10
-rw-r--r--app/models/tag_feed.rb2
2 files changed, 6 insertions, 6 deletions
diff --git a/app/models/status.rb b/app/models/status.rb
index c6e16ff75..96d90e1c2 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -89,19 +89,19 @@ class Status < ApplicationRecord
   scope :without_replies, -> { where('statuses.reply = FALSE OR statuses.in_reply_to_account_id = statuses.account_id') }
   scope :without_reblogs, -> { where('statuses.reblog_of_id IS NULL') }
   scope :with_public_visibility, -> { where(visibility: :public) }
-  scope :tagged_with, ->(tag) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag }) }
+  scope :tagged_with, ->(tag_ids) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag_ids }) }
   scope :in_chosen_languages, ->(account) { where(language: nil).or where(language: account.chosen_languages) }
   scope :excluding_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced_at: nil }) }
   scope :including_silenced_accounts, -> { left_outer_joins(:account).where.not(accounts: { silenced_at: nil }) }
   scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) }
   scope :not_domain_blocked_by_account, ->(account) { account.excluded_from_timeline_domains.blank? ? left_outer_joins(:account) : left_outer_joins(:account).where('accounts.domain IS NULL OR accounts.domain NOT IN (?)', account.excluded_from_timeline_domains) }
-  scope :tagged_with_all, ->(tags) {
-    Array(tags).map(&:id).map(&:to_i).reduce(self) do |result, id|
+  scope :tagged_with_all, ->(tag_ids) {
+    Array(tag_ids).reduce(self) do |result, id|
       result.joins("INNER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}")
     end
   }
-  scope :tagged_with_none, ->(tags) {
-    Array(tags).map(&:id).map(&:to_i).reduce(self) do |result, id|
+  scope :tagged_with_none, ->(tag_ids) {
+    Array(tag_ids).reduce(self) do |result, id|
       result.joins("LEFT OUTER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}")
             .where("t#{id}.tag_id IS NULL")
     end
diff --git a/app/models/tag_feed.rb b/app/models/tag_feed.rb
index 50634fe83..9a16ffc82 100644
--- a/app/models/tag_feed.rb
+++ b/app/models/tag_feed.rb
@@ -52,6 +52,6 @@ class TagFeed < PublicFeed
   end
 
   def tags_for(names)
-    Tag.matching_name(Array(names).take(LIMIT_PER_MODE)) if names.present?
+    Tag.matching_name(Array(names).take(LIMIT_PER_MODE)).pluck(:id) if names.present?
   end
 end