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

115 lines
3.2 KiB

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