From ae008fbc9cd54e8278d58cc4c754895b1203b848 Mon Sep 17 00:00:00 2001 From: kusowl Date: Thu, 5 Mar 2026 13:32:49 +0530 Subject: [PATCH] chore: add isFavorite in produtcs response - refactor code to use query - add active column in products --- backend/app/Data/ProductDTO.php | 4 +++ .../FavouriteProductController.php | 3 +- .../Http/Controllers/ProductController.php | 8 +++-- .../app/Http/Resources/ProductResource.php | 1 + backend/app/Models/Product.php | 21 ++++++++++++++ backend/app/Queries/GetProductsQuery.php | 27 +++++++++++++++++ ...26_03_05_063756_add-active-in-products.php | 29 +++++++++++++++++++ 7 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 backend/app/Queries/GetProductsQuery.php create mode 100644 backend/database/migrations/2026_03_05_063756_add-active-in-products.php diff --git a/backend/app/Data/ProductDTO.php b/backend/app/Data/ProductDTO.php index 64bc2da..4190d09 100644 --- a/backend/app/Data/ProductDTO.php +++ b/backend/app/Data/ProductDTO.php @@ -22,6 +22,7 @@ public function __construct( public array $productImages, public ?string $updatedAt = null, public ?string $createdAt = null, + public ?bool $isFavorite = null ) {} /** @@ -41,6 +42,7 @@ public function toArray(): array $this->productImages), 'updatedAt' => $this->updatedAt, 'createdAt' => $this->createdAt, + 'isFavorite' => $this->isFavorite, ]; } @@ -57,6 +59,8 @@ public static function fromModel(Product $product): self productImages: $product->images->map(fn (ProductImage $productImage) => ProductImageDTO::fromModel($productImage))->all(), updatedAt: $product->updated_at, createdAt: $product->created_at, + // this column is added by where exists query + isFavorite: $product->favorited_by_exists, ); } } diff --git a/backend/app/Http/Controllers/FavouriteProductController.php b/backend/app/Http/Controllers/FavouriteProductController.php index 80e2467..c7a99ac 100644 --- a/backend/app/Http/Controllers/FavouriteProductController.php +++ b/backend/app/Http/Controllers/FavouriteProductController.php @@ -7,6 +7,7 @@ use App\Models\Product; use App\Models\User; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Log; class FavouriteProductController extends Controller { @@ -23,7 +24,7 @@ public function toggle(Request $request, Product $product) $user = $request->user(); $changes = $user->favoriteProducts()->toggle($product); - + Log::info('hi again'); // If changes has any item, that means a product has been attached. $isFavorite = count($changes['attached']) > 0; diff --git a/backend/app/Http/Controllers/ProductController.php b/backend/app/Http/Controllers/ProductController.php index f58296a..c003c10 100644 --- a/backend/app/Http/Controllers/ProductController.php +++ b/backend/app/Http/Controllers/ProductController.php @@ -6,14 +6,16 @@ use App\Http\Requests\CreateProductRequest; use App\Http\Resources\ProductResource; use App\Models\Product; +use App\Queries\GetProductsQuery; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; class ProductController extends Controller { - public function index() + public function index(GetProductsQuery $getProductsQuery) { - $paginator = Product::query()->with(['category:id,name,slug', 'images:id,path,product_id'])->paginate(); - $paginatedDtos = $paginator->through(fn ($product) => ProductDTO::fromModel($product)); + $products = $getProductsQuery->get(Auth::user()); + $paginatedDtos = $products->through(fn ($product) => ProductDTO::fromModel($product)); return ProductResource::collection($paginatedDtos); } diff --git a/backend/app/Http/Resources/ProductResource.php b/backend/app/Http/Resources/ProductResource.php index e650cc7..9749042 100644 --- a/backend/app/Http/Resources/ProductResource.php +++ b/backend/app/Http/Resources/ProductResource.php @@ -30,6 +30,7 @@ public function toArray(Request $request): array return Storage::disk('public')->url($productImage->path); }, $this->resource->productImages), 'updatedAt' => $this->resource->updatedAt, + 'isFavorite' => $this->resource->isFavorite, ]; } } diff --git a/backend/app/Models/Product.php b/backend/app/Models/Product.php index 82c3200..ef200b6 100644 --- a/backend/app/Models/Product.php +++ b/backend/app/Models/Product.php @@ -2,8 +2,11 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Attributes\Scope; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Str; @@ -28,6 +31,17 @@ public function images(): HasMany return $this->hasMany(ProductImage::class, 'product_id', 'id'); } + public function favoritedBy(): BelongsToMany + { + return $this->belongsToMany(User::class, 'favorite_products'); + } + + #[Scope] + protected function active(Builder $query): Builder + { + return $query->where('is_active', true); + } + protected static function booted(): void { static::saving(function ($product) { @@ -36,4 +50,11 @@ protected static function booted(): void } }); } + + protected function casts() + { + return [ + 'is_active' => 'boolean', + ]; + } } diff --git a/backend/app/Queries/GetProductsQuery.php b/backend/app/Queries/GetProductsQuery.php new file mode 100644 index 0000000..4d413c5 --- /dev/null +++ b/backend/app/Queries/GetProductsQuery.php @@ -0,0 +1,27 @@ +active() + ->when($user, function (Builder $query) use ($user) { + $query->withExists( + [ + 'favoritedBy' => fn (Builder $query) => $query->where('user_id', $user->id), + ] + ); + + }) + ->with(['category:id,name,slug', 'images:id,path,product_id']) + ->paginate(); + } +} diff --git a/backend/database/migrations/2026_03_05_063756_add-active-in-products.php b/backend/database/migrations/2026_03_05_063756_add-active-in-products.php new file mode 100644 index 0000000..d315a3b --- /dev/null +++ b/backend/database/migrations/2026_03_05_063756_add-active-in-products.php @@ -0,0 +1,29 @@ +boolean('is_active')->default(true); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('products', function (Blueprint $table) { + $table->dropColumn('is_active'); + }); + + } +};