How to paginate a relationship result in laravel - laravel

How do you paginate the following line
$posts = Category::where('name', request('category'))->firstOrFail()->posts;
in the function below
public function index()
{
$categories = category::all();
if (request('category')) {
$posts = Category::where('name', request('category'))->firstOrFail()->posts;
} else {
$posts = post::where('status', 1)->orderBy('created_at', 'DESC')->paginate(5);
}
return view('user.blog', compact('posts', 'categories'));
}

You have to use the actual relationship method to get access to the query builder:
$posts = Category::where('name', request('category'))
->firstOrFail()
->posts()
->paginate(5);
See the Eloquent docs on Relationship Methods Vs. Dynamic Properties for reference.

Related

How to get top 5 tags of Category from posts Laravel

Hi I've 3 Modeles Post, Tag, and category , post belongs to many categories as well as tags. I want to fetch the top 5 tags of the posts for the given categories but there is no direct relationship between tags and categories.
Following is my eloquent relationship
// Post model
public function categories()
{
return $this->belongsToMany(Category::class, 'post_categories', 'post_id', 'category_id')->withTimestamps();
}
public function tags()
{
return $this->belongsToMany(Tag::class, 'post_tags', 'post_id', 'tag_id')->withTimestamps();
}
// Category Model
public function posts()
{
return $this->belongsToMany(Post::class, 'post_categories', 'category_id', 'post_id')->withTimestamps();
}
// Tag Model
public function posts()
{
return $this->belongsToMany(Post::class, 'post_tags', 'tag_id', 'post_id')->withTimestamps();
}
I have category $category = Category::find($id) for this $category I'm trying to get top 5 tags based on the posts related to this category
Please guide, Thanks in advance
How can I get the top 5 category tags from posts in Laravel?
Controller
$tags = Tag::whereHas('posts' , function (Builder $query) {
$query->whereHas('categories', function ($query,$categoryId) {
$query->where('id', $categoryId);
});
)})
->latest()
->limit(5)
->get();
Alright, I end up using joins
$tags = DB::table('tags')
->select('tags.id', DB::raw('COUNT(tags.id) as tags_count'), DB::raw('FIRST(tag.name)'))
->leftJoin('post_tags', 'tags.id', '=', 'post_tags.tag_id')
->leftJoin('posts', 'posts.id', '=', 'post_tags.post_id')
->leftJoin('post_categories', 'posts.id', '=', 'post_categories.post_id')
->leftJoin('categories', 'categories.id', '=', ''post_categories.category_id')
->where('categories,id', '=', $categoryId)
->groupBy('tags.id')
->orderBy('tags_count', 'DESC')
->limit(5)
->get();

Laravel Eloquent Descending Order

public function blog()
{
$posts = Post::all();
return view('blog')->with( [
'posts' => $posts,
]);
this is my function in the controller
you can do it as below
First method :
$posts = Post::orderBy('created_at', 'DESC')->get();
Second Method :
$posts = Post::latest();
Please view this: https://laravel.com/docs/7.x/eloquent. There are collections methods.
$urvar= Model::orderBy('column_name', 'DESC')->get();

Laravel filter of multiple variables from multiple models

Goodmorning
I'm trying to make a filter with multiple variables for example I want to filter my products on category (for example 'fruit') and then I want to filter on tag (for example 'sale') so as a result I get all my fruits that are on sale. I managed to write seperate filters in laravel for both category and tag, but if I leave them both active in my productsController they go against eachother. I think I have to write one function with if/else-statement but I don't know where to start. Can somebody help me with this please?
These are my functions in my productsController:
public function productsPerTag($id){
$tags = Tag::all();
$products = Product::with(['category','tag','photo'])->where(['tag_id','category_id'] ,'=', $id)->get();
return view('admin.products.index',compact('products','tags'));
}
public function productsPerCategory($id){
$categories = Category::all(); //om het speciefieke id op te vangen heb ik alle categories nodig
$products = Product::with(['category','tag','photo'])->where('category_id', '=', $id)->get();
return view('admin.products.index',compact('products','categories'));
}
These are my routes in web.php. I guess this will also have to change:
Route::get('admin/products/tag/{id}','AdminProductsController#productsPerTag')->name('admin.productsPerTag');
Route::get('admin/products/category/{id}','AdminProductsController#productsPerCategory')->name('admin.productsPerCategory');
For filter both
change your URL like
Route::get('admin/products/tag/{tag_id?}/{category_id?}','AdminProductsController#productsPerTag')->name('admin.productsPerTag');
Make your function into the controller like
public function productsPerTag($tagId = null, $categoryId = null){
$tags = Tag::all();
$categories = Category::all();
$query = Product::with(['category','tag','photo']);
if ($tagId) {
$query->where(['tag_id'] ,'=', $tagId);
}
if ($tagId) {
$query->where(['category_id'] ,'=', $categoryId);
}
$products = $query->get();
return view('admin.products.index',compact('products','tags', 'categories'));
}
You are trying to filter in your query but you pass only 1 parameter to your controller, which is not working.
1) You need to add your filters as query params in the URL, so your url will look like:
admin/products/tag/1?category_id=2
Query parameters are NOT to be put in the web.php. You use them like above when you use the URL and are optional.
2) Change your controller to accept filters:
public function productsPerTag(Request $request)
{
$categoryId = $request->input('category_id', '');
$tags = Tag::all();
$products = Product::with(['category', 'tag', 'photo'])
->where('tag_id', '=', $request->route()->parameter('id'))
->when((! empty($categoryId)), function (Builder $q) use ($categoryId) {
return $q->where('category_id', '=', $categoryId);
})
->get();
return view('admin.products.index', compact('products', 'tags'));
}
Keep in mind that while {id} is a $request->route()->parameter('id')
the query parameters are handled as $request->input('category_id') to retrieve them in controller.
Hope It will give you all you expected outcome if any modification needed let me know:
public function productList($tag_id = null , $category_id = null){
$tags = Tag::all();
$categories = Category::all();
if($tag_id && $category_id) {
$products = Product::with(['category','tag','photo'])
->where('tag_id' , $tag_id)
->where('category_id' , $category_id)
->get();
} elseif($tag_id && !$category_id) {
$products = Product::with(['category','tag','photo'])
->where('tag_id' , $tag_id)
->get();
} elseif($category_id && !$tag_id) {
$products = Product::with(['category','tag','photo'])
->where('category_id' , $category_id)
->get();
} elseif(!$category_id && !$tag_id) {
$products = Product::with(['category','tag','photo'])
->get();
}
return view('admin.products.index',compact(['products','tags','products']));
}
Route:
Route::get('admin/products/tag/{tag_id?}/{category_id?}','AdminProductsController#productsPerTag')->name('admin.productsPerTag');

Laravel Eloquent / keyBy doesn't work with related entity

Code:
public function getPosts(){
$posts = Post::with('meta','taxonomies.terms.termMeta')
->where('post_type','service')
->orderBy('post_name')
->get()
->keyBy('ID')
->toArray();
return $posts;
}
Question :
KeyBy() works when you want to change the entity(ex: Post) key but how to change the related entity key ex: I Want to key post related meta with meta_key.
screenshot
You may need to transform() each post and call the keyBy() method.
public function getPosts(){
$posts = Post::with('meta','taxonomies.terms.termMeta')
->where('post_type','service')
->orderBy('post_name')
->get()
->transform(function ($post) {
$meta = $post->meta;
$post->meta = $meta->keyBy('meta_key');
return $post;
})
->keyBy('ID')
->toArray();
return $posts;
}
Code 1 : doesn't work ,I have noticed that you can alter the $post but not the related entities (ex:meta) :
->transform(function ($post) {
$meta = $post->meta;
$post->meta = $meta->keyBy('meta_key');
return $post;
})
Code 2 : Works but it return only the meta array without the post information
->transform(function ($post) {
$meta = $post->meta;
$post->meta = $meta->keyBy('meta_key');
return $post->meta;
})

How to get article translations in comment relationship?

I have relationship between article and translations, but how can i get that in comment?
$comments = ArticleComments::orderBy('created_at','desc')->with('user')->with('article')->with('translations')->paginate(10);
I tried this also
$comments = ArticleComments::orderBy('created_at','desc')->with('user')->with('article')->with('translations')->whereHas('translations',function($query) use($default_language_id){
$query->where('language_id','=',$default_language_id);
})->paginate(10);
Any suggestion? I get articles but not theirs translations...
Models:
Comment:
public function article()
{
return $this->belongsTo('App\Models\Articles','article_id');
}
Article:
public function translations()
{
return $this->hasMany('App\Models\ArticleTranslations', 'article_id');
}
you should use this :
$comments = ArticleComments::orderBy('created_at','desc')->with('user')->with('article')->with('article.translations')->paginate(10);
for more information :
https://laravel.com/docs/5.3/eloquent-relationships
in Nested Eager Loading section
and if you want add where to query :
$comments = ArticleComments::orderBy('created_at','desc')->with('user')->with('article')->with('article.translations',function($query)
{
$query->where('ANY CONDITION');
})->paginate(10);
It should be like this
$comments = ArticleComments::orderBy('created_at','desc')->with('user')->with('article',function ($query) {
$query->with('translations')
})->paginate(10);

Resources