Reputation: 140
I have a data example like this image
I'd like to get products have tags: phone, 8th and apple (iphone 8)
What is query when I using mysql ?
What is code when I using Laravel Eloquent ORM ?
Sorry for my poor English. Many thanks !
--- Update ---
Here is my query solution, it return my desired product (iPhone 8) but it isn't good solution
SELECT *
FROM products
WHERE id IN (
SELECT product_id
FROM maps
JOIN tags ON maps.tag_id = tags.id
WHERE tags.name = "phone"
AND product_id IN (
SELECT product_id
FROM maps
JOIN tags ON maps.tag_id = tags.id
WHERE tags.name = "8th"
AND product_id IN (
SELECT product_id
FROM maps
JOIN tags ON maps.tag_id = tags.id
WHERE tags.name = "apple"
)
)
)
Upvotes: 1
Views: 728
Reputation: 140
Thanks all answers, this issue has been resolved
Mysql query:
SELECT *
FROM products
WHERE id IN (SELECT product_id FROM maps JOIN tags ON maps.tag_id = tags.id WHERE tags.name = "phone")
AND id IN (SELECT product_id FROM maps JOIN tags ON maps.tag_id = tags.id WHERE tags.name = "8th")
AND id IN (SELECT product_id FROM maps JOIN tags ON maps.tag_id = tags.id WHERE tags.name = "apple");
Laravel code:
$tags = ['phone','8th','apple'];
$products = new Product();
foreach ($tags as $value) {
$query = Map::select('product_id')
->join('tags','maps.tag_id','=','tags.id')
->where('tags.name',$value);
$products = $products->whereIn('id',$query);
}
$products = $products->get();
Upvotes: 0
Reputation: 780
Following is query
SELECT
*
FROM
products
WHERE id IN(
SELECT
DISTINCT maps.product_id
FROM
maps
INNER JOIN tags ON maps.tag_id = tags.id
WHERE
tags.name IN ('phone', '8th', 'apple')
);
Upvotes: 0
Reputation: 2913
First, you need to add relation in your models.
Product Model:
public function tags()
{
return $this->belongsToMany(\App\Tag::class, 'maps', 'product_id', 'tag_id');
}
Tag Model:
public function products()
{
return $this->belongsToMany(\App\Product::class, 'maps', 'tag_id', 'product_id');
}
Now, in order to get the desired products you can do the followings:
$products = Product::whereHas('tags', function ($query) {
$query->where('name', 'phone')
->orWhere('name', '8th')
->orWhere('name', 'apple');
})
->get();
If you have an array of your tag names, then you can do:
$products = Product::whereHas('tags', function ($query) use ($tagNames) {
$query->whereIn('name', $tagNames);
})
->get();
Upvotes: 1
Reputation: 101
You can get all products using Eloquent and Collections.
$tags = Tag::whereIn('name', array('phone', '8th', 'apple'))->with('products')->get();
$products = (collect($tags->pluck('products')))->collapse()->unique('id');
Set products relation in Tag entity.
class Tag extends Model
{
public function products()
{
return $this->belongsToMany('App\Product', 'maps', 'tag_id', 'product_id');
}
}
Upvotes: 0