Class: Api::V1::Reviews::EntriesController

Inherits:
ActionController::API
  • Object
show all
Defined in:
app/controllers/api/v1/reviews/entries_controller.rb

Overview

API endpoint for retrieving product reviews from the local database.

Constant Summary collapse

DEFAULT_PER_PAGE =

Default per page.

50
MAX_PER_PAGE =

Maximum per page.

100

Instance Method Summary collapse

Instance Method Details

#showvoid

This method returns an undefined value.

GET /v1/reviews/entries — paginated, filterable list of reviews for
a given sku, plus rating stats.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'app/controllers/api/v1/reviews/entries_controller.rb', line 21

def show
  sku = params[:sku].to_s.strip
  return render json: { error: 'SKU is required' }, status: :bad_request if sku.blank?

  page = normalize_page(params[:page])
  per_page = normalize_per_page(params[:per_page])

  # Query reviews from the database
  scope = ReviewsIo.active.visible.product_reviews.by_sku(sku)

  # Apply rating filters
  scope = scope.where(rating: params[:rating].to_i) if params[:rating].present?
  scope = scope.where(rating: params[:min_rating].to_i..) if params[:min_rating].present?
  scope = scope.where(rating: ..params[:max_rating].to_i) if params[:max_rating].present?

  # Apply ordering
  scope = case params[:order]
          when 'rating_desc' then scope.order(rating: :desc, review_date: :desc)
          when 'rating_asc' then scope.order(rating: :asc, review_date: :desc)
          when 'date_asc' then scope.order(review_date: :asc)
          else scope.order(review_date: :desc)
          end

  total_count = scope.count
  offset = (page - 1) * per_page
  reviews = scope.limit(per_page).offset(offset)

  # Calculate stats
  stats_scope = ReviewsIo.active.visible.product_reviews.by_sku(sku)
  star_avg = stats_scope.average(:rating)&.round(2)

  payload = {
    reviews: reviews.map { |r| format_review(r) },
    stats: {
      average_rating: star_avg,
      total_reviews: total_count,
      per_page: per_page,
      current_page: page,
      total_pages: (total_count.to_f / per_page).ceil
    }
  }

  render json: payload, status: :ok
end