Laravel.get one related record - php

There is two models: Category and Post.
class Category extends Model
{
public function posts()
{
return $this->hasMany('App\Post','category_id');
}
}
class Post extends Model
{
public function category()
{
return $this->belongsTo('App\Category');
}
}
//Get data
$data = Category::with(['posts' => function($query){
$query->orderBy('id','desc')->first();
}])->get();
In this case, all categories are displayed and only one post. I need to get from each category the one record post.
Example:
Category 1 - Post1
Category 2 - Post2
Category 3 - Post5
Category 4 - Post15
One category - one last post this category.

You have a Category with many Posts, but you just want to get the most recent post so you would add another relationship.
// Category.php
class Category extends Model
{
// This gets ALL posts
public function posts()
{
return $this->hasMany('App\Post','category_id');
}
// This gets the most recent post
// I am ordering by created_at instead of ID, but you can use ID
// if it makes sense for your application)
public function mostRecentPost()
{
return $this->hasOne('App\Post','category_id') // hasOne is the key here
->orderBy('created_at', 'DESC');
}
}
Then when you want to use it...
$data = Category::with('mostRecentPost')->get();

Related

How to get relation of relation Count in laravel?

i have laravel models
Category: id,name
public function posts(){
return $this->hasMany(PostCategory::class,'category_id','id');
}
PostCategory : post_id, category_id
public function post(){
return $this->belongsTo(Post::class,'post_id');
}
POST: id, ..so on
public function solutions(){
return $this->hasMany(PostSolution::class,'post_id','id');
}
I need to get count of all posts fall under a category and also solutions under one category.. there is no direct relation of category and solution so how to get count of solutions in one category.
$categories = Category::withCount('posts')->get();
I think use hasManyThrough relation
// Category Class
public function solutions()
{
return $this->hasManyThrough(PostSolution::class, Post::class);
}
// Then get the data in the same old manner
$categories = Category::->withCount('posts')->get();
I hope this will help

Laravel Eloquent - how to get only 2 child of each parent using Eloquent?

I want to get category with only 2 subcategory not all subcategory. Like below output
Category 1
subcategory 1,
subcategory 2,
Category 2
subcategory 1,
subcategory 2,
Category 3
subcategory 1,
subcategory 2
Total 5 category and each category have 5 subcategory
Category.php
class Category extends Model {
public function subcategory(){
return $this->hasMany('App\Subcategory');
}
public function limitSubcategory(){
return $this->hasMany('App\Subcategory')->limit(2);
}
}
Subcategory.php
class Subcategory extends Model {
public function category(){
return $this->belongsTo('App\Category');
}
}
HomeController.php
Method 1:
Category::with(['limitSubcategory' => function($query) {
}])->get();
Method 2:
Category::with(['subcategory' => function($query) {
$query->limit(2);
}])->get();
But it get only 2 subcategory in first category.
Click here to view output
Please help me, How to get?
you can use the trait: HasEagerLimit:
you can install it:
composer require staudenmeir/eloquent-eager-limit:"^1.0"
and then in your model:
class Category extends Model {
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
public function subcategory(){
return $this->hasMany('App\Subcategory');
}
public function limitSubcategory(){
return $this->hasMany('App\Subcategory')->limit(2);
}
}
and also in SubCategory model:
class Category extends Model {
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
}
now : when you load your relation ... it should return the result you desire:
$results=Category::with('limitSubcategory')->get();
more details in:
https://github.com/staudenmeir/eloquent-eager-limit
In your controller when you retreive Category like this $categ = Category::all() you can have your limited list with $categ->limit_subcategory
If you want to optimise request with eager loading and not have N+1 problem in sql request you can do $categ = Category::whth(['limitSubcategory']->get()
Read this part of documentation for more informations about eager loading https://laravel.com/docs/7.x/eloquent-relationships#eager-loading

Sending posts with a specific category to the view in Laravel

I am making a blog in Laravel Framework. I want to send posts to the frontend view that have a specific category. How can i do this when i have a separate category table that is connected to the posts table?
For example, my posts table has a category_id that is connected to the category table.
Post model:
public function category(){
return $this->belongsTo('App\Category');
}
Category model:
public function posts(){
return $this->hasMany('App\Post');
}
Now, how can i send posts to the view, but only posts that have a specific category, for example "Archive"?
I know it should be something like:
public function index()
{
$rows = Post::notdeleted()->get();
return view('admin.posts.index', compact('rows'));
}
but i dont know how to get the category since it is a category_id 1 in posts table and "archive" in category table.
I think you want to filter the post by category name.
public function index(){
// For example Archive
$categoryName= request()->get('category_name');
$posts = Post::whereHas('category',function($query) use ($categoryName){
$query->where('name','like',"%{$categoryName}%");
});
return view('admin.posts.index', compact('posts'));
}
You can do something like this:
public function index()
{
$rows = Post::whereHas('category',function($q){
$q->where('category_name','archive');
})->get();
return view('admin.posts.index', compact('rows'));
}

How do I get a field from a sub-relation in Laravel?

Objective:
Include category_name field in $posts attributes. The corresponding FK - category_id is currently included in my return.
Controller returns all Posts with their PostChilds
return $posts = Post::with('postchildren')->get();
Post Model hasMany PostChild
public function postchildren() {
$this->hasMany('App\PostChild')
}
PostChild Model hasOne Category
(This table has a category_id field which is a FK for id in the Category model.)
public function category() {
$this->hasOne('App\Category');
}
Category Model
This table has a category_name field
You should be able to get all the categories associated with the children via the HasManyThrough relationship e.g.
class Post
{
public function categories()
{
return $this->hasManyThrough(PostChild::class, Category::class);
}
}
Then you can access the categories directly on the post object e.g.
$categories = Post::first()->categories;
or if you're wanting an array of them something like
$posts = Post::with('categories')->get();
If you always want the categories loaded on the Post class you can define
class Post
{
protected $with = ['categories'];

Laravel relations

I am creating a basic forum just so I have something meaningful to do while learning Laravel.
So just like every forum is organized, on the main page i would like to have a list of categories and their subcategories, a total count of posts in every subcategory while also a link to latest post
So relationship is nested hasMany:
Category -> has Subcategories -> has Threads -> has Posts.
In controller method I have
$cat = Category::with('subcategory')->get();
return View::make('forum.index', compact('cat'));
and this works for basic list of categories and subcategories but I can't figure out the rest.
This sure doesnt work
Category::with('subcategory')->with('threads')->with('posts')->get();
since relation between them is not set. Looking at Laravel docs, there is hasManyThrough relation. Is that a solution?
class Category extends Eloquent {
public function subcategory() {
return $this->hasMany('Subcategory');
}
public function posts() { // not sure about this cause it doesnt work
return $this->hasManyThrough('Post', 'Thread');
}
}
And on top of that how do I get posts->count() for every subcategory? Is it possible to have it split? Chaining could get complicated..
EDIT
Table columns are
Categories
id | title
Subcategory
id | title | category_id
Threads
id | title | subcategory_id | user_id
Posts
id | title | body | thread_id | user_id
EDIT 2
What would be the code for grabing only latest post? This doesnt work
$data = Category::with('subcategories.threads')->with(array('posts' => function($query)
{
$query->take(1);
}))->get();
You have setup only one relation that works and that is:
class Category extends Eloquent {
public function subcategory() {
return $this->hasMany('Subcategory');
}
}
Declare other relationships in other models:
class Subcategory extends Eloquent {
public function threads() {
return $this->hasMany('Thread');
}
}
class Thread extends Eloquent {
public function posts() {
return $this->hasMany('Post');
}
}
Once you have declared relationships then you may use:
$categories = Category::with('subcategory.threads.posts')->get();
Since the one Category has many subcategories so use the plural name for subcategories instead of subcategory in your Category model, so for example, you may use:
class Category extends Eloquent {
public function subcategories() {
return $this->hasMany('Subcategory');
}
}
Then also:
$categories = Category::with('subcategories.threads.posts')->get();
All relationships will be retrieved as nested object collections. For example:
$categories->subcategories; // Will be a collection of Subcategory models
$categories->subcategories->threads // Will be a collection of Thread models
$categories->subcategories->threads->posts // Will be a collection of Post models
You may declare a hasManyThrough relationship between Subcategory and Post using something like this:
class Subcategory extends Eloquent {
public function threads() {
return $this->hasMany('Thread');
}
public function posts() {
return $this->hasManyThrough('Post', 'Thread');
}
}
Also, you may build a relationship between Category and Thread through Subcategory.
I have
QuestionCategory and Questions['category_id'] and ItemsOfQuestion['question_id']
This Code has Work for my I hope that is useful for you
$categories=ExamCategory::with(['question' => function ($query) use($exam){$query->where('exam_id','=',$exam->id)->with('Items');}])->get();

Categories