Improve Account#triadic_closures (#3079)
This commit is contained in:
		
							parent
							
								
									09ec6e504b
								
							
						
					
					
						commit
						682b68438e
					
				
					 2 changed files with 44 additions and 14 deletions
				
			
		|  | @ -259,24 +259,30 @@ class Account < ApplicationRecord | ||||||
|       nil |       nil | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def triadic_closures(account, limit = 5) |     def triadic_closures(account, limit: 5, offset: 0) | ||||||
|       sql = <<-SQL.squish |       sql = <<-SQL.squish | ||||||
|         WITH first_degree AS ( |         WITH first_degree AS ( | ||||||
|             SELECT target_account_id |           SELECT target_account_id | ||||||
|             FROM follows |           FROM follows | ||||||
|             WHERE account_id = :account_id |           WHERE account_id = :account_id | ||||||
|           ) |         ) | ||||||
|         SELECT accounts.* |         SELECT accounts.* | ||||||
|         FROM follows |         FROM follows | ||||||
|         INNER JOIN accounts ON follows.target_account_id = accounts.id |         INNER JOIN accounts ON follows.target_account_id = accounts.id | ||||||
|         WHERE account_id IN (SELECT * FROM first_degree) AND target_account_id NOT IN (SELECT * FROM first_degree) AND target_account_id <> :account_id |         WHERE | ||||||
|  |           account_id IN (SELECT * FROM first_degree) | ||||||
|  |           AND target_account_id NOT IN (SELECT * FROM first_degree) | ||||||
|  |           AND target_account_id NOT IN (:excluded_account_ids) | ||||||
|         GROUP BY target_account_id, accounts.id |         GROUP BY target_account_id, accounts.id | ||||||
|         ORDER BY count(account_id) DESC |         ORDER BY count(account_id) DESC | ||||||
|  |         OFFSET :offset | ||||||
|         LIMIT :limit |         LIMIT :limit | ||||||
|       SQL |       SQL | ||||||
| 
 | 
 | ||||||
|  |       excluded_account_ids = account.excluded_from_timeline_account_ids + [account.id] | ||||||
|  | 
 | ||||||
|       find_by_sql( |       find_by_sql( | ||||||
|         [sql, { account_id: account.id, limit: limit }] |         [sql, { account_id: account.id, excluded_account_ids: excluded_account_ids, limit: limit, offset: offset }] | ||||||
|       ) |       ) | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -261,19 +261,43 @@ RSpec.describe Account, type: :model do | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   describe '.triadic_closures' do |   describe '.triadic_closures' do | ||||||
|     it 'finds accounts you dont follow which are followed by accounts you do follow' do |     subject { described_class.triadic_closures(me) } | ||||||
|       me = Fabricate(:account) | 
 | ||||||
|       friend = Fabricate(:account) |     let!(:me) { Fabricate(:account) } | ||||||
|       friends_friend = Fabricate(:account) |     let!(:friend) { Fabricate(:account) } | ||||||
|  |     let!(:friends_friend) { Fabricate(:account) } | ||||||
|  |     let!(:both_follow) { Fabricate(:account) } | ||||||
|  | 
 | ||||||
|  |     before do | ||||||
|       me.follow!(friend) |       me.follow!(friend) | ||||||
|       friend.follow!(friends_friend) |       friend.follow!(friends_friend) | ||||||
| 
 | 
 | ||||||
|       both_follow = Fabricate(:account) |  | ||||||
|       me.follow!(both_follow) |       me.follow!(both_follow) | ||||||
|       friend.follow!(both_follow) |       friend.follow!(both_follow) | ||||||
|  |     end | ||||||
| 
 | 
 | ||||||
|       results = Account.triadic_closures(me) |     it 'finds accounts you dont follow which are followed by accounts you do follow' do | ||||||
|       expect(results).to eq [friends_friend] |       is_expected.to eq [friends_friend] | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     context 'when you block account' do | ||||||
|  |       before do | ||||||
|  |         me.block!(friends_friend) | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       it 'rejects blocked accounts' do | ||||||
|  |         is_expected.to be_empty | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     context 'when you mute account' do | ||||||
|  |       before do | ||||||
|  |         me.mute!(friends_friend) | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       it 'rejects muted accounts' do | ||||||
|  |         is_expected.to be_empty | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue