How to get all item same category with Eloquent - laravel

Hi all,
I'm building an application in Laravel, I want to get all item in an article category without using this Eloquent.
My code is
$info = Article::find($article_id);
$cate_info = $info->article_categories()->first();
if($cate_info){
$same = Article::with(['article_categories' => function ($query) use ($cate_info){
$query->where('articles_category.ID' ,$cate_info->ID);
}])->where('ID' ,'!=' ,$article_id)->get();
}
And I get all articles. How to solve.
Article and Article_Category is in many to many relationship.
Thanks.

If you want to have all the articles of a particular article_categories you can use whereHas method, now suppose you have name as a field column in categories table, so you can have something like this:
public function getData(Request $request)
{
$category = $request->categoryName;
// $category = 'ABC Category';
$articles = Article::whereHas('article_categories', function($query) use($category) {
$query->where('name', 'like', '%'.$category.'%');
})->get();
return response()->json(['articles' => $articles], 200);
}
Hope this helps.

Related

Laravel whereHas Returns all records

I have have 3 tables in my projects they are:
products(can have Multiple Variants)
variants (belongsto product)
product_attributes (this have product_id,attribute_id,value_id)
I want to filter variants from a product by value ids thats comes from form request as example (1,2,6)
I have tried like this:
$poruduct_id = $request->product_id;
$value_ids = $request->value_ids;
$searched_variants = Variant::whereHas('product.attributeValues', function ($query) use ($value_ids, $product_id) {
$query->whereIn('value_id', [$value_ids]);
})->where('product_id', $product_id)->get();
dd($searched_variants);
But the problem is the query returns all records from the product. What is the solution to filter exactly the values that the product Variants have?
Thank you.
-UPDATED-
I have tried like this but nothing changed
$searched_variants = Variant::select('product_id')->whereHas('product.attributeValues', function ($query) use ($value_ids, $product_id) {
$query->whereIn('value_id', [$value_ids]);
})->groupBy('product_id')
->havingRaw('COUNT(*) = ?', [count((array) $value_ids)])
->get();
-**FİNALLY SOLUTİON**-
I made it like this : I get the value code that is in for example Large the code is L
get all the codes to controller and executed this query ı hope this helps someone
1.$value_codes=$request->value_codes;
2.$value_codes_array=explode(',',$value_codes);
3.$product_id=$request->product_id;
4.$searchValues = preg_split('/,/', $value_codes_array, -1, PREG_SPLIT_NO_EMPTY);
$searchValues = preg_split('/,/', $value_idss, -1, PREG_SPLIT_NO_EMPTY);
$variants= Variant::where(function ($q) use ($searchValues) {
foreach ($searchValues as $value) {
$q->orWhere('sku', 'like', "%-{$value}")
->orWhere('sku', 'like', "%-{$value}-%")
->orWhere('sku', 'like', "{$value}-%");
}
})->where('product_id',$product_id)->get();
dd($variants);
If you have n variants to one product, you query should be like:
Product Model
public function variants: HasMany relationships
//usage
$produtc->variants->and here the query function
You need to use it in this way, it should work:
$productId = $request->product_id;
$valueIds = $request->value_ids;
$searchedVariants = Variant::whereHas('product.attributeValues', function ($query) use ($valueIds) {
$query->distinct()->whereIn('value_id', $valueIds);
}, '=', count($valueIds))->where('product_id', $productId)->get();

how to add Limit() to pivot table

I have two tables products and categories and a pivot table category_product.
I have added relation in Product.php is below.
public function categories()
{
return $this->belongsToMany(Category::class);
}
I have added relation in Category.php is below.
public function products()
{
return $this->belongsToMany(Product::class);
}
Both are working fine.
But what I want is, I want to take all the categories which has products and the products should not return more than 6 records.
Meaning I have a two categories Music, Movies and both have more than 50+ products.
The code should be return only 6 products for both Music, Movies categories.
This is what I tried,
Category::with(['products' => function ($query){
return $query->select()->limit(6);
}, 'products.properties'])
->whereHas('products', function ($query){
return $query->select()->limit(6);
})->when($slug, function($query) use($slug){
$query->whereIn('slug', $slug);
})->get();
and this,
Category::addSelect([
'products' => Product::select('id')->whereColumn('products.id', 'categories.id')->orderBy('id')->limit(6)
])->when($slug, function($query) use($slug){
$query->whereIn('slug', $slug);
})->get()
Second try returns error,
"stripos() expects parameter 1 to be string, object given"
I am using laravel 6.
Thanks in advance, any answers and suggestion welcome.
Added My Answer Below
please use this. Also add all your logics to eloquent, not in controller.
public function categories()
{
return $this->belongsToMany(Category::class)->limit(6);
}
I found a solution for my question. Please have a check and please advice me if any better way to solve it.(mainly I want to reduce the number of queries)
The solution is
public function getProductsBasedOnCategory(array $slug){
$categories = Category::select()->when($slug, function($query) use($slug){
$query->whereIn('slug', $slug);
})->get();
$res = new Collection();
foreach ($categories as $category){
$category->products = $category->products()->limit(6)->get();
$res->push($category);
}
return $res;
}
This function executing queries how many categories I have.
If I have 10 categories, its executing 10 queries. Exclude $categories query
Is this answer is good or you have any better solution. I want to reduce the number of queries execution.
Please suggest.
you can use like below.
$cat = Category::with('products')->when($slug, function($query) use($slug){
$query->whereIn('slug', $slug);
})->get();
foreach ($cat as $key => $value) {
$value->products->first();
}

Laravel eloquent paginate in relation is not displayed in collection

I want to page the relation articles. The correct number is displayed but not in the collection, for example "first page" or "to last".
$articles = Categories::where('slug', $categorie)->with(['articles' => function ($query) use ($default_count, $default_sort) {
$query->orderBy('price', $default_sort)
->with('contents')
->paginate(2);
}])->first();
What am I missing here?
Try flipping it around so that Article is the top level:
$articles = Article::with('contents')
->whereHas('category', function ($query) use ($categorie) {
$query->where('slug', $categorie);
})
->orderBy('price', $default_sort)
->paginate(2);
This assumes that you have the category relationship set up on Article as well.
i think you want result some like that
Article::whereHas('category', function ($query) use ($categories) {
$query->where('slug', $categories);
})
->with('contents')
->orderBy('price', $default_sort)
->paginate(2);

Property [***] does not exist on this collection instance Laravel eloquent relationship

In my Post Model
public function user()
{
return $this->belongsTo('App\User');
}
And in the User Model
public function posts()
{
return $this->hasMany('App\Post');
}
Now I am trying to get the comments of a specific user
$user= User::where('name', 'like', '%Mat%')->first();
return $user->posts->comment;
But it shows
Property [comment] does not exist on this collection instance.
The user has many posts which therefore returns a collection, you will need to loop over this to get your comments out. I.e.
$user = User::where('name', 'like', '%Mat%')->first();
$user->posts->each(function($post) {
echo $post->comment;
});
See the documentation on Laravel Collections
I think you can try this :
$user= User::with('post')->where('name', 'like', '%Mat%')->get();
$postComment = array();
foreach($user->post as $post){
$postComment = $post->comment;
}
return $postComment;
Hope this help for you !!!
If you want to have all comments you can use the following code:
$comments = [];
$user = User::where('name', 'like', '%Mat%')->with(['post.comment' => function($query) use (&$comments) {
$comments = $query->get();
}])->first();
return $comments;
Property [comment] does not exist on this collection instance.
The above error occurs because the Posts function returns a collection. Now you will have to traverse through each element of the collection.
Since, you are returning $user->posts()->comment, I am assuming you need it in the form of an array and don't have to simply echo them out, one by one. So you can store them all in an array & then process it whatever whay you like.
$comments = array();
$user->posts()->each(function $post){
$comments = $post->comment;
}
return $comments;
For greater insight, into this collection function read:
https://laravel.com/docs/5.4/collections#method-each

Multiple Category Nested Query Laravel 5

I've followed this code structure for a multi-level category system on Laravel 5:
This works fine. But I'm trying to put together a query to return posts in a category (by slug) but also the children categories underneath.
So heres what I've got at the moment:
$posts = Post::with('images')->whereHas('categories', function($q) use ($slug)
{
$q->where('slug', '=', $slug);
})->orderBy('created_at', 'DESC')->paginate(10);
This returns everything under the category that matches the slug passed through, but not the children. Any suggestions?
Thanks.
If you have only one depth of subcategories, the following solution is what I would use.
<?php
$category = Category::where('slug',$slug)->first();
$posts = Post::with('images')->whereHas('categories', function($q) use ($category)
{
$q->where(function($q) use ($category) {
$q->where('id', $category->id)->orWhere('parent_id',$category->id);
});
})->orderBy('created_at', 'DESC')->paginate(10);
In your code, you only fetched the Posts and their images. If I understood correctly, what you want to fetch are the Posts, their images, the category their in and childCategories (this is a made up name) of that category. You just need to add category.childCategories in your with method like so:
$posts = Post::with('images', 'categories.childCategories')->whereHas('categories', function($q) use ($slug)
{
$q->where('slug', '=', $slug);
})->orderBy('created_at', 'DESC')->paginate(10);
Remember to change the childCategories name to whatever the child category relationship name in your Category model.

Resources