Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🤖 Add Active Model Serializers and Update Product Serialization #655

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions react/src/components/Products.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,13 @@ function Products({ frontendSlowdown, backend, productsExtremelySlow, productsBe
<div>
<ul className="products-list">
{products.map((product, i) => {
// Ensure reviews is an array and handle edge cases
const reviews = Array.isArray(product.reviews) ? product.reviews : [];
const averageRating = (
product.reviews.reduce((a, b) => a + (b['rating'] || 0), 0) /
product.reviews.length
reviews.length > 0
? reviews.reduce((a, b) => a + (b['rating'] || 0), 0) / reviews.length
: 0
).toFixed(1);

let stars = [1, 2, 3, 4, 5].map((index) => {
if (index <= averageRating) {
return (
Expand Down
2 changes: 2 additions & 0 deletions ruby-on-rails/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ gem 'nokogiri', '~>1.17.2'
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
gem 'rack-cors'
gem 'pg'
# Add serializer for proper JSON handling
gem 'active_model_serializers', '~> 0.10.13'

gem "stackprof"
gem "sentry-ruby"
Expand Down
28 changes: 7 additions & 21 deletions ruby-on-rails/app/controllers/api/v1/products_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,18 @@ def index
# get Sentry tags in application_controller.rb
set_Sentry_tags


transaction = Sentry.get_current_scope.get_transaction || Sentry.start_transaction(name: "custom transaction")

span_products_db = transaction.start_child(op: "custom.products_db_call")
sleep 0.25
products = Products.select("id, title, description, descriptionfull, price, img, imgcropped, Null as pg_sleep, Null as reviews")
sleep 0.25
# Eager load reviews to prevent n+1 queries and ensure proper serialization
products = Products.includes(:reviews)
.select("id, title, description, descriptionfull, price, img, imgcropped")
span_products_db.finish

# n+1 to db if done this way
products.each do |prod_slow|
span_products_slow_db = transaction.start_child(op: "custom.reviews_slow_db_call")
prod_slow["pg_sleep"] = ""
prod_slow["reviews"] = []
prod_slow["reviews"] = Reviews.select("id, productid, rating, customerid, description, created, Null as pg_sleep").where("productid="+prod_slow.id.to_s)
span_products_slow_db.finish
end

# fewer db calls this way -- done in products-join
# span_reviews_db = transaction.start_child(op: "custom.reviews_db_call")
# sleep 0.25
# reviews = Reviews.select("id, productid, rating, customerid, description, created, Null as pg_sleep")
# sleep 0.25
# span_reviews_db.finish

# span_response = transaction.start_child(op: "custom.construct_response_object")
# products.each do |prod|
# Use the serializer to properly format the response
render json: products, each_serializer: ProductSerializer, status: 200
end
# prod["pg_sleep"] = ""
# reviews_arr = []
# reviews.each do |review|
Expand Down
18 changes: 18 additions & 0 deletions ruby-on-rails/app/serializers/product_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class ProductSerializer < ActiveModel::Serializer
attributes :id, :title, :description, :descriptionfull, :price, :img, :imgcropped, :pg_sleep, :reviews

def reviews
reviews_relation = object.reviews.select("id, productid, rating, customerid, description, created")
reviews_relation.map do |review|
{
id: review.id,
productid: review.productid,
rating: review.rating,
customerid: review.customerid,
description: review.description,
created: review.created,
pg_sleep: nil
}
end
end
end
Loading