diff --git a/app/controllers/api/v0/tags_controller.rb b/app/controllers/api/v0/tags_controller.rb index 461d548ac..fe8e7a08a 100644 --- a/app/controllers/api/v0/tags_controller.rb +++ b/app/controllers/api/v0/tags_controller.rb @@ -3,19 +3,17 @@ module Api class TagsController < ApiController before_action :set_cache_control_headers, only: %i[index] - ATTRIBUTES_FOR_SERIALIZATION = %i[id name bg_color_hex text_color_hex short_summary badge_id].freeze + ATTRIBUTES_FOR_SERIALIZATION = %i[id name bg_color_hex text_color_hex].freeze private_constant :ATTRIBUTES_FOR_SERIALIZATION def index - @tags = Tag.includes(:badge).select(ATTRIBUTES_FOR_SERIALIZATION) - page = params[:page] per_page = (params[:per_page] || 10).to_i num = [per_page, 1000].min - @tags = @tags.where(id: params[:tag_ids]) if params[:tag_ids].present? - - @tags = @tags.order(taggings_count: :desc).page(page).per(num) + @tags = Tag.select(ATTRIBUTES_FOR_SERIALIZATION) + .order(taggings_count: :desc) + .page(page).per(num) set_surrogate_key_header Tag.table_key, @tags.map(&:record_key) end diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index b08c0ed55..5217591f7 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -3,7 +3,7 @@ class TagsController < ApplicationController before_action :authenticate_user!, only: %i[edit update] after_action :verify_authorized - ATTRIBUTES_FOR_SERIALIZATION = %i[id name bg_color_hex text_color_hex].freeze + ATTRIBUTES_FOR_SERIALIZATION = %i[id name bg_color_hex text_color_hex short_summary badge_id].freeze INDEX_API_ATTRIBUTES = %i[name rules_html short_summary bg_color_hex badge_id].freeze TAGS_ALLOWED_PARAMS = %i[ @@ -21,6 +21,24 @@ class TagsController < ApplicationController @tags = params[:q].present? ? tags.search_by_name(params[:q]) : tags.order(hotness_score: :desc) end + def bulk + skip_authorization + @tags = Tag.includes(:badge).select(ATTRIBUTES_FOR_SERIALIZATION) + + page = params[:page] + per_page = (params[:per_page] || 10).to_i + num = [per_page, 1000].min + + if params[:tag_ids].present? + @tags = @tags.where(id: params[:tag_ids]) + elsif params[:tag_names].present? + @tags = @tags.where(name: params[:tag_names]) + end + + @tags = @tags.order(taggings_count: :desc).page(page).per(num) + render json: @tags, only: ATTRIBUTES_FOR_SERIALIZATION, include: [badge: { only: [:badge_image] }] + end + def edit @tag = Tag.find_by!(name: params[:tag]) authorize @tag diff --git a/app/views/api/v0/tags/index.json.jbuilder b/app/views/api/v0/tags/index.json.jbuilder index aa7017efd..f95de7d02 100644 --- a/app/views/api/v0/tags/index.json.jbuilder +++ b/app/views/api/v0/tags/index.json.jbuilder @@ -1,10 +1,3 @@ json.array! @tags.each do |tag| - json.extract!(tag, :id, :name, :bg_color_hex, :text_color_hex, :short_summary) - json.badge do - if tag.badge - json.badge_image tag.badge.badge_image - else - json.badge_image nil - end - end + json.extract!(tag, :id, :name, :bg_color_hex, :text_color_hex) end diff --git a/config/routes.rb b/config/routes.rb index bf01d6844..224f0fd95 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -151,6 +151,7 @@ Rails.application.routes.draw do collection do get "/onboarding", to: "tags#onboarding" get "/suggest", to: "tags#suggest", defaults: { format: :json } + get "/bulk", to: "tags#bulk", defaults: { format: :json } end end resources :stripe_active_cards, only: %i[create update destroy] diff --git a/spec/requests/api/v0/tags_spec.rb b/spec/requests/api/v0/tags_spec.rb index cee0dca01..53cca6680 100644 --- a/spec/requests/api/v0/tags_spec.rb +++ b/spec/requests/api/v0/tags_spec.rb @@ -21,9 +21,6 @@ RSpec.describe "Api::V0::Tags", type: :request do response_tag_with_badge = response.parsed_body.last expect_valid_json_body(response_tag, tag) expect_valid_json_body(response_tag_with_badge, tag_with_badge) - - expect(response_tag["badge"]["badge_image"]).to be_nil - expect(response_tag_with_badge["badge"]["badge_image"]["url"]).to eq(tag_with_badge.badge.badge_image.url) end it "orders tags by taggings_count in a descending order" do @@ -36,15 +33,6 @@ RSpec.describe "Api::V0::Tags", type: :request do expect(response.parsed_body.map { |t| t["id"] }).to eq(expected_result) end - it "finds tags from array of tag_ids" do - tags = create_list(:tag, 10, taggings_count: 10) - tag_ids = tags.sample(4).map(&:id) - - get api_tags_path, params: { tag_ids: tag_ids } - - expect(response.parsed_body.map { |t| t["id"] }).to match_array(tag_ids) - end - it "supports pagination" do create_list(:tag, 3) @@ -68,13 +56,10 @@ RSpec.describe "Api::V0::Tags", type: :request do private def expect_valid_json_body(body, tag) - expect(body.keys).to match_array(%w[id name bg_color_hex text_color_hex short_summary badge]) + expect(body.keys).to match_array(%w[id name bg_color_hex text_color_hex]) expect(body["id"]).to eq(tag.id) expect(body["name"]).to eq(tag.name) expect(body["bg_color_hex"]).to eq(tag.bg_color_hex) expect(body["text_color_hex"]).to eq(tag.text_color_hex) - expect(body["short_summary"]).to eq(tag.short_summary) - expect(body).to have_key("badge") - expect(body["badge"]).to have_key("badge_image") end end diff --git a/spec/requests/tags_spec.rb b/spec/requests/tags_spec.rb index 08137f9bc..2f62d3afc 100644 --- a/spec/requests/tags_spec.rb +++ b/spec/requests/tags_spec.rb @@ -34,6 +34,38 @@ RSpec.describe "Tags", type: :request, proper_status: true do end end + describe "GET /tags/bulk" do + it "returns a JSON representation of the top tags", :aggregate_failures do + tags = create_list(:tag, 10, taggings_count: 10) + tag_names = tags.sample(2).map(&:name) + tag_ids = tags.sample(4).map(&:id) + + get bulk_tags_path, params: { tag_names: tag_names, tag_ids: tag_ids } + + expect(response.parsed_body.map { |t| t["id"] }).to match_array(tag_ids) + expect(response).to have_http_status(:ok) + expect(response.content_type).to match(%r{application/json; charset=utf-8}i) + end + + it "finds tags from array of tag_ids" do + tags = create_list(:tag, 10, taggings_count: 10) + tag_ids = tags.sample(4).map(&:id) + + get bulk_tags_path, params: { tag_ids: tag_ids } + + expect(response.parsed_body.map { |t| t["id"] }).to match_array(tag_ids) + end + + it "finds tags from array of tag_names" do + tags = create_list(:tag, 10, taggings_count: 10) + tag_names = tags.sample(4).map(&:name) + + get bulk_tags_path, params: { tag_names: tag_names } + + expect(response.parsed_body.map { |t| t["name"] }).to match_array(tag_names) + end + end + describe "GET /tags/suggest" do it "returns a JSON representation of the top tags", :aggregate_failures do badge = create(:badge)