Laravel Eloquent Convert user_id to user info - php

I've some relationships in my Model classes.
Consume this relationship:
We've Post() model which store our posts data. Each post in this table has a user_id column that has one to many relationship with User() Mode (the author of the post)
class User extends Model {
public function posts()
{
return $this->hasMany('App\Post');
}
}
class Post extends Model {
public function user()
{
return $this->belongsTo('App\User');
}
}
So when i want to return my post with elequent, I'll get something like this:
{
"user_id": 1,
"title": "Foo name",
"body": "Foo body",
},
{
"user_id": 1,
"title": "Bar name",
"body": "another Bar body",
}
But i want to get something like this:
{
"user_id": 1,
"user": {
'name'=> 'John',
'last'=> 'Maco',
},
"title": "Foo name",
"body": "Foo body",
},
{
"user_id": 1,
"user": {
'name'=> 'John',
'last'=> 'Maco',
},
"title": "Bar name",
"body": "another Bar body",
}

You need to declare the relation from Post to User
Post.php
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
Then you will be able to load the user with every post like #dparoli commented
$post = Post::with('user')->get();

Related

Get the collection instead of the ID

I have a many-to-many relationship between three tables (Courses , Professors , Hours) I created a 4th table called course_hour_professors to make the relation and I made it one-to-many relationship between the 4 tables because I know that if I get a pivot table with more than two FKs, I have to treat it as full model. So instead of Many-to-Many relationship. I have to divide it into multiple of One-to-Many relationships. all of this is working now but Professors table is related to User table and I need to access the professor name which is located in the User table since it's related to it but I can only access the User_id from my course_hour_professors as shown below :
{
"id": 3,
"professor_id": 94,
"course_id": 132,
"hour_id": 1,
"nbr_hour_course": 9,
"course": {
"id": 132,
"created_at": "2018-07-25T16:02:19.000000Z",
"updated_at": "2018-09-07T07:38:01.000000Z",
"name": "Algèbre - 1"
},
"professor": {
"id": 94,
"created_at": "2018-09-24T08:18:30.000000Z",
"updated_at": "2019-10-23T14:32:00.000000Z",
"user_id": 810,
"grade": "Maître assistant",
"cin_delivered_at": "le 20/05/2015",
"cnrps": "********",
"cnss": "00000000",
"phone": "********"
},
"hour": {
"id": 1,
"heure_suivie": 13,
"type": "jour",
"created_at": "2021-08-19T20:02:16.000000Z",
"updated_at": "2021-08-05T20:02:16.000000Z",
"week_id": 1
}
}
Professor Model :
class professor extends Model
{
public function user()
{
return $this->belongsTo("App\User",'user_id','id');
}
public function courses()
{
return $this->belongsToMany('App\course');
}
public function hours()
{
return $this->belongsToMany('App\Hour');
}
public function courseHourProfessor()
{
return $this->hasMany('App\CourseHourProfessor', 'professor_id','id');
}
}
CourseHourProfessor Model :
class CourseHourProfessor extends Model
{
public function professor()
{
return $this->belongsTo('App\professor', 'professor_id');
}
public function course()
{
return $this->belongsTo('App\course', 'course_id');
}
public function hour()
{
return $this->belongsTo('App\Hour', 'hour_id');
}
}
Course Model
class Course extends Model
{
public function professor()
{
return $this->belongsToMany('App\professor');
}
public function hours()
{
return $this->belongsToMany('App\Hour');
}
public function courseHourProfessor()
{
return $this->hasMany('App\CourseHourProfessor', 'course_id','id');
}
}
Hour Model :
class Hour extends Model
{
//
public function week()
{
return $this->belongsTo(Week::class);
}
public function courses()
{
return $this->belongsToMany('App\course');
}
public function professors()
{
return $this->belongsToMany('App\professor');
}
public function courseHourProfessor()
{
return $this->hasMany('App\CourseHourProfessor', 'hour_id','id');
}
}
CourseHourProfessor Controller :
public function getById($id)
{
return CourseHourProfessor::with(['course','professor','hour'])->where('id', $id)->get();
}
I want to know if it's possible for the result to be like this
{
"id": 3,
"professor_id": 94,
"course_id": 132,
"hour_id": 1,
"nbr_hour_course": 9,
"course": {
"id": 132,
"created_at": "2018-07-25T16:02:19.000000Z",
"updated_at": "2018-09-07T07:38:01.000000Z",
"name": "Algèbre - 1"
},
"professor": {
"id": 94,
"created_at": "2018-09-24T08:18:30.000000Z",
"updated_at": "2019-10-23T14:32:00.000000Z",
"user_id": 810,
"grade": "Maître assistant",
"cin_delivered_at": "le 20/05/2015",
"cnrps": "********",
"cnss": "00000000",
"phone": "********"
"user": {
"id": 60,
"email": "********#gmail.com",
"name": "Aymen",
"lastname": "********",
"type": "professor",
"birthday": "2018-01-01",
"gender": "Male",
"image_id": 34,
"cin": "********",
"fullname": "********Aymen"
}
},
"hour": {
"id": 1,
"heure_suivie": 13,
"type": "jour",
"created_at": "2021-08-19T20:02:16.000000Z",
"updated_at": "2021-08-05T20:02:16.000000Z",
"week_id": 1
}
}
yes, what you want is a json :)
public function getById($id)
{
return CourseHourProfessor::with(['course','professor','hour'])->find($id)->toJson();
}

Laravel appends only one attribute from relationship

I'm trying to add an extra field to my Laravel 7 API model:
class Layer extends Model {
protected $fillable = ['name', 'filename', 'status', 'category_id'];
protected $appends = ['category_name'];
public function getCategoryNameAttribute()
{
return $this->category->name;
}
public function category()
{
return $this->belongsTo('App\LayerCategory', 'category_id');
}
}
My Controller:
.....
public function index()
{
return Layer::orderBy('name', 'asc')->paginate();
}
.....
I expect the following response:
{
"id": 1,
"category_id": 1,
"name": "My Layer",
"filename": "file_name.zip",
"status": true,
"category_name": "My category name"
}
But I receive:
{
"id": 1,
"category_id": 1,
"name": "My Layer",
"filename": "file_name.zip",
"status": true,
"category_name": "My category name",
"category": [
"id": 1,
"name": "My category name",
"status": true
]
}
How to return only the category name?
PS: I also tried with Resources.
Since you're eager loading the Category relationship to get category_name, you'll need to add logic to hide category from your JSON response. This can be done using the Hidden attribute on Serialization:
protected $hidden = ['category'];
You can read https://laravel.com/docs/7.x/eloquent-serialization#hiding-attributes-from-json for more information.

How to return a nested JSON format with given table structure using Laravel

If I have some table structure as below, how should I return the following JSON format using Eloquent ORM?
Table structure:
authors
id - integer
name - string
posts
id - integer
author_id - integer
title - string
images
id - integer
post_id - integer
filename - string
JSON format I expect to return:
[
{
"id": 1,
"name": "Jeffrey",
"posts": [
{
"id": 1,
"title": "Hello World",
"images": [
{
"id": 12,
"filename": "my-image.jpg"
},
{
"id": 13,
"filename": "your-image.jpg"
}
]
},
{
"id": 5,
"title": "Lorem Ipsum",
"images": [
{
"id": 20,
"filename": "his-image.jpg"
},
{
"id": 22,
"filename": "her-image.jpg"
}
]
}
]
}
]
Table structure: an author may have many posts, a post may have many images
JSON format: images are nested in post, posts are nested in author
Edited
Thanks for the reminder, I also added their Models:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Author extends Model
{
public function posts()
{
return $this->hasMany('App\Post');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function author()
{
return $this->belongsTo('App\Author');
}
public function images()
{
return $this->hasMany('App\Image');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
public function post()
{
return $this->belongsTo('App\Post');
}
}
If you add the relation Posts to your Author model and relation Images to your Posts model you will be able to make the request like this and it will take all of the data for you.
Author::with('posts.images')->get();

Laravel Relationship between 3 tables

so I am trying to get the category name and this is what I have
tablets:
categories: id,name
post_categories: id, post_id, category_id
post : id, columns
I have the models: Post, PostCategory and Category.
Post Model :
public function categories()
{
return $this->hasMany('App\PostCategory');
}
PostCategory Model :
public function category()
{
return $this->hasMany(Category::class, 'id', 'category_id');
}
and in the controller I have
return Post::with('categories.category')->orderby('id','desc')->get();
And my result is
[
{
"id": 50,
"categories": [
{
"id": 92,
"category_id": 11,
"category": [
{
"id": 11,
"name": "JXrfLHdQVNON",
"image": null
}
]
}
]
}
]
and i wanted it to be something like
[
{
"id": 50,
"categories": [
{
"id": 1,
"name": "category_name",
"image": null
}
]
}
]
Is there a way to do it? I have been playing around with this and havent manage to find a easy way to do it
inside your Post model :
public function categories()
{
return $this->belongsToMany('App\Model\Category','post_categories','post_id','category_id')->withTimestamps();
}
in your controller :
return Post::with('categories:id,name,image')->orderBy('id','desc')->get();
This is a many-to-many relationship. Make sure you have your relationship set up correctly. If you want to choose specific columns you can do:
return Post::with('categories.category:id,name')->orderby('id','desc')->get();
It will return the columns id, name from category table/ model. You must specify id doing that.
https://laravel.com/docs/5.7/eloquent-relationships#many-to-many
https://laravel.com/docs/5.7/eloquent-relationships#eager-loading

Laravel/Eloquent mutate model on join

I'm trying to mutate a model to display an array of strings and not an array of objects.
Current Output
{
"id": 1,
"company_name": "blah"
"language": [
{
"name": "English"
},
{
"name": "French"
}
]
},
{
"id": 2,
"company_name": "blah2"
"language": [
{
"name": "English"
},
{
"name": "French"
}
]
}
Desired Output
{
"id": 1,
"company_name": "blah"
"language": ["English","French"]
},
{
"id": 2,
"company_name": "blah2"
"language": ["English","French"]
}
Partner Model
class Partner extends Eloquent
{
protected $table = 'property_managers';
protected $visible = array('id','company_name','language');
public function language(){
return $this->belongsToMany('Language', 'property_manager_language', 'property_manager_id', 'language_id');
}
}
Language Model
class Language extends Eloquent
{
protected $table = 'languages';
protected $visible = array('name');
public function propertyManager()
{
return $this->belongsToMany('PropertyManager');
}
}
I'm accessing it via the code snippet below
$pm = Partner::with('language')->get();
I looked into mutators but it doesn't seem to hit that attribute within the partner model.
public function getLanguageAttribute(){
//run my code to flatten to array
}
So I'm curious as to if mutators don't work on joins or how you would be able to modify the return on the join. I can add a mutator to the Language model but that will only modify the attributes of that specific model. Any insight would be helpful. Thanks
In your model,
public function getLanguagesAttribute(){
return array_pluck(collect($this->language)->toArray(), 'name');
}
luego prueba con esto
$partner = Partner::find(1);
return $partner->languages;

Categories