Skip to content

Sort personal projects on profile page by last_activity_at

What does this MR do and why?

The list of personal projects (for example on personal profile page) is now ordered by the project updated_at field. This MR will change that to last_activity_at, so it is consistent with project lists on group pages.

The specs are now expecting the returned project list to be sorted.

Changelog: changed

Related issue: #432410 (closed)

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Screenshots or screen recordings

Before After
before after

Database-related change

The order clause changed:

  • master: ORDER BY project.updated_at DESC
  • branch: ORDER BY project.last_activity_at DESC

Both fields have indexes.

Plan for master branch

 Sort  (cost=42.66..42.67 rows=1 width=824) (actual time=9.281..9.395 rows=1404 loops=1)
   Sort Key: projects.updated_at DESC
   Sort Method: quicksort  Memory: 1125kB
   Buffers: shared hit=1341
   I/O Timings: read=0.000 write=0.000
   ->  Nested Loop  (cost=1.00..42.65 rows=1 width=824) (actual time=0.074..6.395 rows=1404 loops=1)
         Buffers: shared hit=1338
         I/O Timings: read=0.000 write=0.000
         ->  Index Scan using index_namespaces_on_owner_id on public.namespaces  (cost=0.56..3.58 rows=1 width=4) (actual time=0.028..0.029 rows=1 loops=1)
               Index Cond: (namespaces.owner_id = 208581)
               Filter: ((namespaces.type)::text = 'User'::text)
               Rows Removed by Filter: 0
               Buffers: shared hit=5
               I/O Timings: read=0.000 write=0.000
         ->  Index Scan using index_projects_on_namespace_id_and_repository_size_limit on public.projects  (cost=0.44..39.04 rows=3 width=824) (actual time=0.043..5.434 rows=1404 loops=1)
               Index Cond: (projects.namespace_id = namespaces.id)
               Filter: (projects.visibility_level = 20)
               Rows Removed by Filter: 5
               Buffers: shared hit=1333
               I/O Timings: read=0.000 write=0.000

Plan for this branch

 Sort  (cost=42.66..42.67 rows=1 width=824) (actual time=2975.503..2975.777 rows=1404 loops=1)
   Sort Key: projects.last_activity_at DESC
   Sort Method: quicksort  Memory: 1125kB
   Buffers: shared hit=8 read=1333 dirtied=14
   I/O Timings: read=2914.132 write=0.000
   ->  Nested Loop  (cost=1.00..42.65 rows=1 width=824) (actual time=35.524..2955.256 rows=1404 loops=1)
         Buffers: shared hit=5 read=1333 dirtied=14
         I/O Timings: read=2914.132 write=0.000
         ->  Index Scan using index_namespaces_on_owner_id on public.namespaces  (cost=0.56..3.58 rows=1 width=4) (actual time=19.393..19.396 rows=1 loops=1)
               Index Cond: (namespaces.owner_id = 208581)
               Filter: ((namespaces.type)::text = 'User'::text)
               Rows Removed by Filter: 0
               Buffers: shared hit=2 read=3
               I/O Timings: read=19.076 write=0.000
         ->  Index Scan using index_projects_on_namespace_id_and_repository_size_limit on public.projects  (cost=0.44..39.04 rows=3 width=824) (actual time=16.105..2929.013 rows=1404 loops=1)
               Index Cond: (projects.namespace_id = namespaces.id)
               Filter: (projects.visibility_level = 20)
               Rows Removed by Filter: 5
               Buffers: shared hit=3 read=1330 dirtied=14
               I/O Timings: read=2895.056 write=0.000

How to set up and validate locally

GDK: Create three projects for user root, using this snippet in a Rails console:

Snippet
current_user = User.find(1)
activity_timestamps = [2.months.ago, 6.months.ago, 1.day.ago]
params = {namespace_id: current_user.namespace.id}

3.times do |i|
  last_activity_at = activity_timestamps[i]
  project_params = params.merge(name: "Last Activity at #{last_activity_at.to_date}")

  project = ::Projects::CreateService.new(current_user, project_params).execute

  project.update(last_activity_at: last_activity_at)
end
  • Login on gdk using root account
  • Goto http://localhost:3000/root
  • On master: the personal project list should be ordered like the before image
  • On this branch: ordered by last_activity_at

Related to #432410 (closed)

Edited by Rutger Wessels

Merge request reports