Add ability to bulk search tags by name or id (#16671)
* Trigger Build * Remove cache header before_action and add ability to search by tag name * Remove cache header before_action and add ability to search by tag name * Add internal bulk tag endpoint to get tags by array of names or ids * Restore V0 tags controller
This commit is contained in:
parent
e0e4003671
commit
ab224d34b2
6 changed files with 58 additions and 31 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue