feat: tag-based product alternatives
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
fbb4862454
commit
c4e6173e46
@@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
@@ -173,6 +174,31 @@ class Product extends Model
|
||||
return $this->belongsToMany(Tag::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get approved products sharing tags with this one, best matches first.
|
||||
* Single query; each result has a shared_tags_count attribute.
|
||||
*/
|
||||
public function alternatives(int $limit = 3): Collection
|
||||
{
|
||||
return static::query()
|
||||
->approved()
|
||||
->where('products.id', '!=', $this->id)
|
||||
->join('product_tag', 'product_tag.product_id', '=', 'products.id')
|
||||
->whereIn('product_tag.tag_id', function ($query) {
|
||||
$query->select('tag_id')->from('product_tag')->where('product_id', $this->id);
|
||||
})
|
||||
->select('products.*')
|
||||
->selectRaw('COUNT(product_tag.tag_id) as shared_tags_count')
|
||||
->withCount('upvotes')
|
||||
->groupBy('products.id')
|
||||
->orderByDesc('shared_tags_count')
|
||||
->orderByDesc('upvotes_count')
|
||||
->orderByDesc('products.created_at')
|
||||
->orderByDesc('products.id')
|
||||
->limit($limit)
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to only include approved products.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user