Return all relationship data in laravel - php

I want to retrieve data using eloquent model and return it in the following json response.
user[
transactions[],
clients[
ubications[],
contactos[],
plans[],
]
]
Currently I am receiving user,transcation and clients data but I am not able to retreive the data inside client property e.g ubications[],contactos[] and plans[].So I need help regarding the sub properties as I have already implemented the relationship.
Here are the models I am using
User.php
class User extends Authenticatable
{
use Notifiable,HasApiTokens;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'username', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function token(){
return $this->access_token;
}
public function transaction(){
return $this->hasMany(Transaction::class);
}
public function plan(){
return $this->hasManyThrough(Plan::class,Client::class);
}
public function ubication(){
return $this->hasManyThrough(Ubicacion::class,Client::class);
}
public function contacto(){
return $this->hasManyThrough(Contacto::class,Client::class);
}
public function client(){
return $this->hasMany(Client::class);
}
}
Client.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Client extends Model
{
protected $fillable=[
'nombre',
'ruc',
'status',
'user_id'
];
public function contacto(){
return $this->hasMany(Contacto::class);
}
public function feedback(){
return $this->hasMany(Feedback::class);
}
public function plan(){
return $this->hasMany(Plan::class);
}
public function ubication(){
return $this->hasMany(Ubicacion::class);
}
public function user(){
return $this->belongsTo(User::class);
}
}

You can use nested data Eager Loading:
Laravel Documentation Eager Loading
$user = User::find(1)
->with('clients', 'clients.contacto', 'clients.ubications', 'clients.plans')
->get();

Related

how can i handle this error : Undefined offset: 0

I'm producing an online school platform and in part of it student can see it's classes with their informations..but the related function return this error : Undefined offset: 0 (View: C:\xampp\htdocs\OnlineSchool\resources\views\admin\student\ClassReport.blade.php)
there are some relations between models
My Models:
USER(students and teachers) ، LEVEL(level of classes) ، Classroom.
=> there is a many to many relation between student and classroom (pivot table)
please save me from this stupid error
user:
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password','image','level','code_meli',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function classroom(){
return $this->hasMany (classroom::class);
}
public function ClassRoomStudent(){
return $this->belongsToMany (classroom::class ,'classroom_user','user_id','classroom_id');
}
}
classroom:
class classroom extends Model
{
protected $fillable = [
'title', 'teacher_id', 'level_id','day','time','price',
];
public function Student(){
return $this->belongsToMany (user::class ,'classroom_user','classroom_id','user_id');
}
public function level(){
return $this->belongsTo (level::class );
}
public function teacher(){
return $this->belongsTo (user::class );
}
}
level :
class level extends Model
{
protected $fillable = [
'title',
];
public function classroom(){
return $this->hasMany (classroom::class);
}
public function exam(){
return $this->hasMany (exam::class);
}
}
and my function in controller:
public function MyClasses(){
$student_id=auth ()->user ()->id;
$classrooms=classroom::with ('level','teacher','factor')->wherehas('student',function ($q) use($student_id){
$q->where('id',$student_id);
})->get();
return view ('admin.student.ClassReport',compact ('classrooms','student_id'));
}
at the end .. my blade:
#foreach($classrooms as $class)
<tr>
<td>{{$i++}}</td>
<td>{{$class->title}}</td>
<td>{{$class->teacher[0]->name}}</td>
.
.
.
.
</tr>
#endforeach
The Classroom belongs to only one teacher, no need to use de zero index, just type $class->teacher->name

Laravel return Has many relationship

The relationship is User who can have many Events they are associated to.
I want to be able to make an API call to get all the events associated by the user. I have changed my primary key from id to uuid. I have made the foreign key association to the Events table as well. The primary key in the events table is also a column called UUID.
I am getting error
Return value of App\Http\Controllers\UsersController::getAllEvents() must be an instance of App\Http\Resources\UserResource, instance of Illuminate\Database\Eloquent\Relations\HasMany returned
My routes table:
Route::apiResource('/users', 'UsersController');
Route::apiResource('/events', 'EventsController');
Route::get('/users/allevents/{user}', 'UsersController#getAllEvents');
So the URL im hitting is:
http://127.0.0.1:8000/api/users/allevents/0a0jqZ7qzuhemKnzB3wOPUc2Ugp2
0a0jqZ7qzuhemKnzB3wOPUc2Ugp2 is the UUID of a user. I want to get all the events associated to that user.
My User model:
class User extends Model
{
use Notifiable;
use SoftDeletes;
protected $dates = ['deleted_at'];
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'uuid', 'email', 'firstName', 'lastName', 'level', 'venmo'
];
public function getRouteKeyName()
{
return 'uuid';
}
public function events() {
return $this->hasMany(Event::class);
}
}
My Event Model:
class Event extends Model
{
use SoftDeletes;
protected $table = 'events';
protected $dates = ['deleted_at'];
// public function getRouteKeyName()
// {
// return 'uuid';
// }
protected $fillable = [
'id', 'availableSpots', 'uuid', 'chosenDate', 'date', 'epochTime', 'level', 'price', 'time', 'created_at', 'updated_at', 'user_uuid'
];
public $incrementing = false;
protected $primaryKey = 'uuid';
protected $keyType = 'string';
public function user(){
return $this->belongsTo(User::class, 'user_uuid', 'uuid');
}
}
My UsersController:
class UsersController extends Controller
{
public function show(User $user): UserResource
{
return new UserResource($user);
}
/**
* #param Request $request
* #param User $user
* #return UserResource
*/
public function update(Request $request, User $user): UserResource
{
$user->update($request->all());
return new UserResource($user);
}
/**
* #param User $user
* #return UserResource
* #throws \Exception
*/
public function destroy(User $user): UserResource
{
$user->delete();
return new UserResource($user);
}
public function getAllEvents(User $user): UserResource {
return $user->events();
}
}
You are using wrong type of the method return it doesn't return UserResource it return events array so by removing the wrong type it will work
public function getAllEvents(User $user) {
return $user->events;
}
public function getAllEvents(User $user)
{
return $user->events;
}

Get user avatar attribute from post relation

In Laravel 5.8, I have a custom attribute to recover the avatar via Gravatar. This is an attribute in the User model.
/**
* #return string
*/
public function getAvatarAttribute()
{
return sprintf('%s%s%s', 'https://secure.gravatar.com/avatar/', md5(strtolower(trim($this->email))), '?s=200');
}
I have a belongsTo/hasMany relationship in the Post/User model.
Post model:
/**
* #return BelongsTo
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
User model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* #var string
*/
protected $table = 'users';
/**
* #var array
*/
protected $fillable = [
'username',
'email',
'password',
'api_token',
];
/**
* #var array
*/
protected $hidden = [
'password',
'remember_token',
'api_token',
];
/**
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
'admin' => 'boolean',
];
/**
* #return string
*/
public function getRouteKeyName()
{
return 'username';
}
/**
* #return HasMany
*/
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
/**
* #return string
*/
public function getAvatarAttribute()
{
return sprintf('%s%s%s', 'https://secure.gravatar.com/avatar/', md5(strtolower(trim($this->email))), '?s=200');
}
}
I pass the post by the URL of the route:
Route::get('post/{post}', 'BlogController#post');
I would like to retrieve the avatar attribute via post. Only, I recover a null. And I do not understand where it comes from.
public function post(Post $post)
{
dd($post->user); // user model without appends attributes
dd($post->user->avatar); // null
}
I found the problem, I used User from Illuminate (Illuminate\Foundation\Auth\User) instead my User model.

Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name laravel 5.4

Hi following are my relations
User Model
public function loginlogout()
{
$this->HasMany("App\Models\LoginLogoutLogs");
}
and this is my LoginLogoutLogs Model
public function users()
{
return $this->belongsTo('App\Models\User');
}
I am trying to access name from Users like this
$loginLogoutLogs = LoginLogoutLogs::all();
foreach($loginLogoutLogs as $loginLogoutLog){
dd($loginLogoutLog->users()->name);
}
but i am getting this error
Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name
EDIT Adding Models
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Zizaco\Entrust\Traits\EntrustUserTrait;
use Session;
use Illuminate\Support\Facades\DB;
class User extends Authenticatable
{
use Notifiable;
use EntrustUserTrait;
protected $table = 'tbl_users';
protected $primaryKey = 'id';
protected $guarded = ['id'];
const API = 'api';
const WEB = 'web';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'last_login', 'Address', 'Age', 'DateOfBirth', 'created_by', 'deleted_by'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'is_admin' => 'boolean',
];
public function isAdmin()
{
return $this->is_admin;
}
static function GetUserNamebyID($id)
{
$name = User::select("name")->where(["id" => $id])->pluck('name');
if (isset($name[0])) {
return $name[0];
} else {
return '';
}
}
public function loginlogout()
{
$this->HasMany("App\Models\LoginLogoutLogs", 'userID');
}
public function company()
{
$this->HasMany("App\Models\Company");
}
}
And now LoginLogouts Model
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Zizaco\Entrust\Traits\EntrustUserTrait;
use Illuminate\Database\Eloquent\Model;
use Session;
use Illuminate\Support\Facades\DB;
class LoginLogoutLogs extends Model
{
use Notifiable;
use EntrustUserTrait;
protected $table = 'tbl_users_logs';
protected $primaryKey = 'id';
protected $guarded = ['id'];
const API = 'api';
const WEB = 'web';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'userID','is_accpeted','type','addedFrom'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'is_admin' => 'boolean',
];
public function isAdmin()
{
return $this->is_admin;
}
// change company to hasmany
public function user()
{
return $this->belongsTo('App\Models\User');
}
}
simply change your part of
dd($loginLogoutLog->users()->name);
into
dd($loginLogoutLog->users->name);
remove the bracket on users, its the easy fix.
here we obtain a property, not a function.... (although in the model its defined as function)
Easy fix:
$loginLogoutLogs = LoginLogoutLogs::all();
foreach($loginLogoutLogs as $loginLogoutLog){
dd($loginLogoutLog->users->name);
}
You want to access the relationship entities, as opposed to the relationship model.
By using users(), your code thinks you are trying to call a name() method on the users model, as opposed to your users method on the LoginLogoutLogs class.
You need to change your relationship with user adding the foreign key in LoginLogoutLogs:
public function user()
{
return $this->belongsTo('App\Models\User', 'userID');
}
Also ensure that you call user insted of users
$loginLogoutLogs = LoginLogoutLogs::all();
foreach($loginLogoutLogs as $loginLogoutLog){
dd($loginLogoutLog->user->name);
}
And if you want to perform use eager loading:
$loginLogoutLogs = LoginLogoutLogs::with('user')->get();
foreach($loginLogoutLogs as $loginLogoutLog){
dd($loginLogoutLog->user->name);
}
Remove () when you are getting the child model and add a second parameter to belongsTo.
Here you are:
Migrations:
// Parent migration (create_clients_table):
Schema::create('clients', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
// Child migration (create_payments_table):
Schema::create('payments', function (Blueprint $table) {
$table->unsignedBigInteger('client_id');
$table->foreign('client_id')
->references('id')
->on('clients')
->onDelete('cascade');
});
Models relationship:
// Child (Client Model)
public function owner()
{
return $this->belongsTo(User::class, 'user_id');
}
// Parent (User Model)
public function clients()
{
return $this->hasMany(Client::class);
}
Data output:
// Route:
Route::get('/client/{id}/payments', [PaymentController::class, 'paymentsOfClient']);
// In controller (PaymentController):
/**
* Display a listing of the payments of specified Client.
*
* #param string $id
* #return \Illuminate\Http\Response
*/
public function paymentsOfClient($id)
{
$client = Client::find($id);
// check permissions
if (auth()->user()->id !== $client->owner->id) {
return;
}
$payments = $client->payments()->paginate(20);
return response()->json($payments);
}

How to access other related model data in Laravel?

I am creating a user profile page and I want to retrieve the data from my User model and UserProfile model. But I have a problem in getting the result. Here's what I did:
User model
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'username',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/*
public function isAdmin() {
return $this->admin;
}
*/
public function profile() {
return $this->hasOne('App\UserProfile');
}
}
UserProfile model
class UserProfile extends Model
{
protected $table = 'user_profile';
protected $fillable = [
'phone',
'address'
];
public function user() {
return $this->belongsTo('App\User');
}
}
Then I access the relation in my ProfileController
public function getProfile($username) {
$user = User::with('user_profile')->where('username', $username)->get();
dd($user);
}
And I got this error:
Call to undefined relationship [user_profile] on model [App\User].
The user_profile is my table name
Use proper relationship name:
$user = User::with('profile')->where('username', $username)->first();
Also, in this case you should use the first() method to get an user object.

Categories