ぼざクリ タグ広場 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.
 
 
 
 
 
 

128 lines
3.4 KiB

  1. require 'open-uri'
  2. require 'nokogiri'
  3. class PostsController < ApplicationController
  4. # GET /posts
  5. def index
  6. limit = (params[:limit] || 20).to_i
  7. cursor = params[:cursor]
  8. q = filtered_posts.order(created_at: :desc)
  9. next_cursor = nil
  10. if cursor.present?
  11. q = q.where('posts.created_at < ?', Time.iso8601(cursor))
  12. end
  13. posts = q.limit(limit + 1)
  14. next_cursor = nil
  15. if posts.size > limit
  16. next_cursor = posts.last.created_at.iso8601(6)
  17. posts = posts.first(limit)
  18. end
  19. render json: { posts: posts.as_json(include: { tags: { only: [:id, :name, :category, :post_count] } }),
  20. next_cursor: }
  21. end
  22. def random
  23. post = filtered_posts.order('RAND()').first
  24. return head :not_found unless post
  25. viewed = current_user&.viewed?(post) || false
  26. render json: (post
  27. .as_json(include: { tags: { only: [:id, :name, :category] } })
  28. .merge(viewed: viewed))
  29. end
  30. # GET /posts/1
  31. def show
  32. post = Post.includes(:tags).find(params[:id])
  33. return head :not_found unless post
  34. viewed = current_user&.viewed?(post) || false
  35. render json: (post
  36. .as_json(include: { tags: { only: [:id, :name, :category] } })
  37. .merge(viewed: viewed))
  38. end
  39. # POST /posts
  40. def create
  41. return head :unauthorized unless current_user
  42. return head :forbidden unless ['admin', 'member'].include?(current_user.role)
  43. # TODO: URL が正規のものがチェック,不正ならエラー
  44. title = params[:title]
  45. post = Post.new(title:, url: params[:url], thumbnail_base: '', uploaded_user: current_user)
  46. post.thumbnail.attach(params[:thumbnail])
  47. if post.save
  48. post.resized_thumbnail!
  49. if params[:tags].present?
  50. tag_ids = JSON.parse(params[:tags])
  51. post.tags = Tag.where(id: tag_ids)
  52. end
  53. render json: post, status: :created
  54. else
  55. render json: { errors: post.errors.full_messages }, status: :unprocessable_entity
  56. end
  57. end
  58. def viewed
  59. return head :unauthorized unless current_user
  60. current_user.viewed_posts << Post.find(params[:id])
  61. head :no_content
  62. end
  63. def unviewed
  64. return head :unauthorized unless current_user
  65. current_user.viewed_posts.delete(Post.find(params[:id]))
  66. head :no_content
  67. end
  68. # PATCH/PUT /posts/1
  69. def update
  70. return head :unauthorized unless current_user
  71. return head :forbidden unless ['admin', 'member'].include?(current_user.role)
  72. post = Post.find(params[:id])
  73. tag_ids = JSON.parse(params[:tags])
  74. if post.update(title: params[:title], tags: Tag.where(id: tag_ids))
  75. render({ json: (post
  76. .as_json(include: { tags: { only: [:id, :name, :category] } })),
  77. status: :created })
  78. else
  79. render json: post.errors, status: :unprocessable_entity
  80. end
  81. end
  82. # DELETE /posts/1
  83. def destroy
  84. end
  85. private
  86. def filtered_posts
  87. tag_names = params[:tags]&.split(?\ )
  88. match_type = params[:match]
  89. tag_names.present? ? filter_posts_by_tags(tag_names, match_type) : Post.all
  90. end
  91. def filter_posts_by_tags tag_names, match_type
  92. posts = Post.joins(:tags)
  93. if match_type == 'any'
  94. posts = posts.where(tags: { name: tag_names }).distinct
  95. else
  96. tag_names.each do |tag|
  97. posts = posts.where(id: Post.joins(:tags).where(tags: { name: tag }))
  98. end
  99. end
  100. posts.distinct
  101. end
  102. end