This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
class TagVersionsController < ApplicationController
|
||||
def index
|
||||
tag_id = params[:id].presence
|
||||
page = (params[:page].presence || 1).to_i
|
||||
limit = (params[:limit].presence || 20).to_i
|
||||
|
||||
page = 1 if page < 1
|
||||
limit = 1 if limit < 1
|
||||
|
||||
offset = (page - 1) * limit
|
||||
|
||||
q = TagVersion.joins(<<~SQL.squish)
|
||||
LEFT JOIN
|
||||
tag_versions prev
|
||||
ON
|
||||
prev.tag_id = tag_versions.tag_id
|
||||
AND prev.version_no = tag_versions.version_no - 1
|
||||
SQL
|
||||
.select('tag_versions.*', 'prev.name AS prev_name', 'prev.category AS prev_category',
|
||||
'prev.aliases AS prev_aliases', 'prev.parent_tag_ids AS prev_parent_tag_ids')
|
||||
q = q.where('tag_versions.tag_id = ?', tag_id) if tag_id
|
||||
|
||||
count = q.except(:select, :order, :limit, :offset).count
|
||||
|
||||
versions = q.order(Arel.sql('tag_versions.created_at DESC, tag_versions.id DESC'))
|
||||
.limit(limit)
|
||||
.offset(offset)
|
||||
|
||||
render json: { versions: serialise_versions(versions), count: }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def serialise_versions rows
|
||||
user_ids = rows.map(&:created_by_user_id).compact.uniq
|
||||
users_by_id = User.where(id: user_ids).pluck(:id, :name).to_h
|
||||
|
||||
rows.map do |row|
|
||||
cur_aliases = split_values(row.aliases)
|
||||
prev_aliases = split_values(row.attributes['prev_aliases'])
|
||||
|
||||
cur_parent_tags =
|
||||
TagRepr.many(
|
||||
Tag
|
||||
.includes(:tag_name, :materials, { tag_name: :wiki_page })
|
||||
.where(id: split_parent_tag_ids(row.parent_tag_ids))
|
||||
.to_a)
|
||||
prev_parent_tags =
|
||||
TagRepr.many(
|
||||
Tag
|
||||
.includes(:tag_name, :materials, { tag_name: :wiki_page })
|
||||
.where(id: split_parent_tag_ids(row.attributes['prev_parent_tag_ids']))
|
||||
.to_a)
|
||||
|
||||
{ tag_id: row.tag_id,
|
||||
version_no: row.version_no,
|
||||
event_type: row.event_type,
|
||||
name: { current: row.name, prev: row.attributes['prev_name'] },
|
||||
category: { current: row.category, prev: row.attributes['prev_category'] },
|
||||
aliases: build_version_values(cur_aliases, prev_aliases, key: :name),
|
||||
parent_tags: build_version_values(cur_parent_tags, prev_parent_tags, key: :tag),
|
||||
created_at: row.created_at.iso8601,
|
||||
created_by_user: row.created_by_user_id &&
|
||||
{ id: row.created_by_user_id,
|
||||
name: users_by_id[row.created_by_user_id] } }
|
||||
end
|
||||
end
|
||||
|
||||
def build_version_values cur_values, prev_values, key:
|
||||
(cur_values | prev_values).map do |value|
|
||||
type =
|
||||
if cur_values.include?(value) && prev_values.include?(value)
|
||||
'context'
|
||||
elsif cur_values.include?(value)
|
||||
'added'
|
||||
else
|
||||
'removed'
|
||||
end
|
||||
|
||||
{ key => value, type: }
|
||||
end
|
||||
end
|
||||
|
||||
def split_values(values) = values.to_s.split(/\s+/).reject(&:blank?)
|
||||
|
||||
def split_parent_tag_ids(values) = split_values(values).map(&:to_i)
|
||||
end
|
||||
Reference in New Issue
Block a user