friends_of_friends_source.rb 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. # frozen_string_literal: true
  2. class AccountSuggestions::FriendsOfFriendsSource < AccountSuggestions::Source
  3. def get(account, limit: 10)
  4. Account.find_by_sql([<<~SQL.squish, { id: account.id, limit: limit }]).map { |row| [row.id, key] }
  5. WITH first_degree AS (
  6. SELECT target_account_id
  7. FROM follows
  8. JOIN accounts AS target_accounts ON follows.target_account_id = target_accounts.id
  9. WHERE account_id = :id
  10. AND NOT target_accounts.hide_collections
  11. )
  12. SELECT accounts.id, COUNT(*) AS frequency
  13. FROM accounts
  14. JOIN follows ON follows.target_account_id = accounts.id
  15. JOIN account_stats ON account_stats.account_id = accounts.id
  16. LEFT OUTER JOIN follow_recommendation_mutes ON follow_recommendation_mutes.target_account_id = accounts.id AND follow_recommendation_mutes.account_id = :id
  17. WHERE follows.account_id IN (SELECT * FROM first_degree)
  18. AND NOT EXISTS (SELECT 1 FROM follows f WHERE f.target_account_id = follows.target_account_id AND f.account_id = :id)
  19. AND follows.target_account_id <> :id
  20. AND accounts.discoverable
  21. AND accounts.suspended_at IS NULL
  22. AND accounts.silenced_at IS NULL
  23. AND accounts.moved_to_account_id IS NULL
  24. AND follow_recommendation_mutes.target_account_id IS NULL
  25. GROUP BY accounts.id, account_stats.id
  26. ORDER BY frequency DESC, account_stats.followers_count ASC
  27. LIMIT :limit
  28. SQL
  29. end
  30. private
  31. def key
  32. :friends_of_friends
  33. end
  34. end