Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#8369] Refactor timeline method in AdminGeneralController #8458

Merged
merged 1 commit into from
Nov 22, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 42 additions & 54 deletions app/controllers/admin_general_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,50 +103,14 @@ def timeline
@events_title = get_events_title

@events = WillPaginate::Collection.create((params[:page] or 1), 100) do |pager|
# create a hash for each model type being returned
info_request_event_ids = {}
public_body_version_ids = {}
comment_ids = {}
# get the relevant slice from the paginator
timestamps = get_timestamps
timestamps.slice(pager.offset, pager.per_page).each_with_index do |event, index|
# for each event in the slice, add an item to the hash for the model type
# whose key is the model id, and value is the position in the slice
if event[1] == 'InfoRequestEvent'
info_request_event_ids[event[0].to_i] = index
elsif event[1] == 'Comment'
comment_ids[event[0].to_i] = index
else
public_body_version_ids[event[0].to_i] = index
end
end
# get all the models in the slice, eagerly loading the associations we use in the view
public_body_versions = PublicBody.versioned_class.
includes(public_body: :translations).
find(public_body_version_ids.keys)
info_request_events = InfoRequestEvent.
includes(:info_request).
find(info_request_event_ids.keys)
comments = Comment.where(event_type: 'destroy_comment').
includes(:info_request).
find(comment_ids.keys)
@events = []
# drop the models into a combined array, ordered by their position in the timestamp slice
public_body_versions.each do |version|
@events[public_body_version_ids[version.id]] = [version, version.updated_at]
end
info_request_events.each do |event|
@events[info_request_event_ids[event.id]] = [event, event.created_at]
end
comments.each do |comment|
@events[comment_ids[comment.id]] = [comment, comment.created_at]
end
events, count = get_timeline_events(pager)

# inject the result array into the paginated collection:
pager.replace(@events)
pager.replace(events)

# set the total entries for the page to the overall number of results
pager.total_entries = timestamps.size
pager.total_entries = count
end
end

Expand Down Expand Up @@ -186,33 +150,57 @@ def get_events_title
end
end

def get_timestamps
# Get an array of event attributes within the timespan in the format
# [id, type_of_model, event_timestamp]
def get_timeline_events(pager)
# Get an array of events, timestamps and total record count within the
# timespan in the selected event type
#
# Note that the relevant date for InfoRequestEvents is creation, but
# for PublicBodyVersions is update throughout
connection = InfoRequestEvent.connection

authority_change_scope = PublicBody.versioned_class.
select("id, 'PublicBodyVersion', updated_at AS timestamp").
select("id, 'PublicBody::Version' as type, updated_at AS timestamp").
where(updated_at: start_date...).
order(timestamp: :desc)
order(timestamp: :desc).
limit(pager.per_page).
offset(pager.offset)
authority_change_count = authority_change_scope.
unscope(:select, :order, :limit, :offset).
count

info_request_event_scope = InfoRequestEvent.
select("id, 'InfoRequestEvent', created_at AS timestamp").
select("id, 'InfoRequestEvent' as type, created_at AS timestamp").
where(created_at: start_date...).
order(timestamp: :desc)
order(timestamp: :desc).
limit(pager.per_page).
offset(pager.offset)
info_request_event_count = info_request_event_scope.
unscope(:select, :order, :limit, :offset).
count

case params[:event_type]
when 'authority_change'
connection.select_rows(authority_change_scope.to_sql)
count = authority_change_count
scope = authority_change_scope
when 'info_request_event'
connection.select_rows(info_request_event_scope.to_sql)
count = info_request_event_count
scope = info_request_event_scope
else
connection.select_rows("#{info_request_event_scope.unscope(:order).to_sql}
UNION
#{authority_change_scope.unscope(:order).to_sql}
ORDER by timestamp desc")
count = authority_change_count + info_request_event_count
query = ActiveRecord::Base.sanitize_sql_array(
[<<~SQL.squish, limit: pager.per_page, offset: pager.offset]
(#{authority_change_scope.unscope(:order, :limit, :offset).to_sql})
UNION ALL
(#{info_request_event_scope.unscope(:order, :limit, :offset).to_sql})
ORDER BY timestamp DESC
LIMIT :limit OFFSET :offset
SQL
)
scope = ActiveRecord::Base.connection.select_all(query)
end

records_and_timestamps = scope.map do |record|
[record['type'].constantize.find(record['id']), record['timestamp']]
end

[records_and_timestamps, count]
end
end
Loading