ぼざクリタグ広場 https://hub.nizika.monster
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

120 lines
3.5 KiB

  1. class PostVersionsController < ApplicationController
  2. def index
  3. post_id = params[:post].presence
  4. tag_id = params[:tag].presence
  5. page = (params[:page].presence || 1).to_i
  6. limit = (params[:limit].presence || 20).to_i
  7. page = 1 if page < 1
  8. limit = 1 if limit < 1
  9. offset = (page - 1) * limit
  10. tag_name =
  11. if tag_id
  12. TagName.joins(:tag).find_by(tag: { id: tag_id })
  13. end
  14. return render json: { versions: [], count: 0 } if tag_id && tag_name.blank?
  15. q = PostVersion.joins(<<~SQL.squish)
  16. LEFT JOIN
  17. post_versions prev
  18. ON
  19. prev.post_id = post_versions.post_id
  20. AND prev.version_no = post_versions.version_no - 1
  21. SQL
  22. .select('post_versions.*', 'prev.title AS prev_title', 'prev.url AS prev_url',
  23. 'prev.thumbnail_base AS prev_thumbnail_base', 'prev.tags AS prev_tags',
  24. 'prev.original_created_from AS prev_original_created_from',
  25. 'prev.original_created_before AS prev_original_created_before')
  26. q = q.where('post_versions.post_id = ?', post_id) if post_id
  27. if tag_name
  28. escaped = ActiveRecord::Base.sanitize_sql_like(tag_name.name)
  29. q = q.where(("CONCAT(' ', post_versions.tags, ' ') LIKE :kw " +
  30. "OR CONCAT(' ', prev.tags, ' ') LIKE :kw"),
  31. kw: "% #{ escaped } %")
  32. end
  33. count = q.except(:select, :order, :limit, :offset).count
  34. versions = q.order(Arel.sql('post_versions.created_at DESC, post_versions.id DESC'))
  35. .limit(limit)
  36. .offset(offset)
  37. render json: { versions: serialise_versions(versions), count: }
  38. end
  39. private
  40. def serialise_versions rows
  41. user_ids = rows.map(&:created_by_user_id).compact.uniq
  42. users_by_id = User.where(id: user_ids).pluck(:id, :name).to_h
  43. rows.map do |row|
  44. cur_tags = split_tags(row.tags)
  45. prev_tags = split_tags(row.attributes['prev_tags'])
  46. {
  47. post_id: row.post_id,
  48. version_no: row.version_no,
  49. event_type: row.event_type,
  50. title: {
  51. current: row.title,
  52. prev: row.attributes['prev_title']
  53. },
  54. url: {
  55. current: row.url,
  56. prev: row.attributes['prev_url']
  57. },
  58. thumbnail: {
  59. current: nil,
  60. prev: nil
  61. },
  62. thumbnail_base: {
  63. current: row.thumbnail_base,
  64. prev: row.attributes['prev_thumbnail_base']
  65. },
  66. tags: build_version_tags(cur_tags, prev_tags),
  67. original_created_from: {
  68. current: row.original_created_from&.iso8601,
  69. prev: row.attributes['prev_original_created_from']&.iso8601
  70. },
  71. original_created_before: {
  72. current: row.original_created_before&.iso8601,
  73. prev: row.attributes['prev_original_created_before']&.iso8601
  74. },
  75. created_at: row.created_at.iso8601,
  76. created_by_user:
  77. if row.created_by_user_id
  78. {
  79. id: row.created_by_user_id,
  80. name: users_by_id[row.created_by_user_id]
  81. }
  82. end
  83. }
  84. end
  85. end
  86. def build_version_tags(cur_tags, prev_tags)
  87. (cur_tags | prev_tags).map do |name|
  88. type =
  89. if cur_tags.include?(name) && prev_tags.include?(name)
  90. 'context'
  91. elsif cur_tags.include?(name)
  92. 'added'
  93. else
  94. 'removed'
  95. end
  96. {
  97. name:,
  98. type:
  99. }
  100. end
  101. end
  102. def split_tags(tags)
  103. tags.to_s.split(/\s+/).reject(&:blank?)
  104. end
  105. end