laravel 5.3 error : Trying to get property of non-object - php

Laravel 5.3
I am trying to get the fields from tables users and mobiles
users table has a primary key id
and my mobiles tables has a field users_id
so I want to get all the numbers of all users_id
select u.*,m.mobile,ud.name from users u
left join userdetails ud on ud.user_id = u.id
left join mobiles m on m.users_id = u.id
where m.mobiletypes_id = 1 and m.deleted_by is null
I am trying the above query in eloquent but I am facing an error
undefined property illuminate database eloquent collection
my user model
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'email', 'password','role_id'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function mobile()
{
return $this->hasMany('App\mobile','users_id');
}
public function userdetails()
{
return $this->hasOne('App\Userdetails');
}
}
my mobile model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class mobile extends Model
{
protected $primaryKey = 'mobiles_id';
protected $fillable = ['mobile', 'mobiletypes_id', 'users_id', 'created_by', 'updated_by', 'deleted_by', 'created_at', 'updated_at'];
}
my controller
public function employeeview(){
// $user = User::all(); // get all user
$userdetails = User::with(['mobile' => function ($query) {
$query->where('mobiletypes_id', 1);
} ,'userdetails'])->get(); // get all userdetails
// $mobile = User::with('mobile')->get();
//$userdetails = User::all();
//return $user;
//return view('employeeview',compact('userdetails'));
return view('employeeview')->with('userdetails', $userdetails);
}
my view employeeview.blade.php
#foreach($userdetails as $u)
<tr>
<td>{{$u->id}} </td>
<td>{{$u->userdetails->name}} </td>
<td>{{$u->email}}</td>
#foreach($u->mobile as $um)
<td>{{$um->mobile}}</td>
#endforeach
</tr>
#endforeach

I would first advise to place a dd($userdetails) before the return of the view, in order to check that it is indeed what you're looking for.
If needed, create a variable called
$visible = []
and place all the visible fields inside it.

Related

How to show list of data based on the user in Laravel

I have two table (three actually, but in this context it's only related to these two tables), Pekerjaan and User. Both table are in eloquent. User hasMany pekerjaans, and Pekerjaan belongsTo User. In the User table it has status 'super' and 'ppk'. 'Super' is a super admin whereby it can view all data, and for 'ppk' it can only view certain data based on his/her USER_ID in Pekerjaan's table. Here is my code for User.php model:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Jetstream\HasProfilePhoto;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Database\Eloquent\Model as Eloquent;
class User extends Authenticatable
{
use HasApiTokens;
use HasFactory;
use HasProfilePhoto;
use Notifiable;
use TwoFactorAuthenticatable;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'name',
'email',
'username',
'satker',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
'two_factor_recovery_codes',
'two_factor_secret',
];
/**
* The attributes that should be cast.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* The accessors to append to the model's array form.
*
* #var array
*/
protected $appends = [
'profile_photo_url',
];
public function pekerjaans(){
return $this->hasMany(Pekerjaan::class);
}
}
And here is the Pekerjaan.php model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model as Eloquent;
class Pekerjaan extends Eloquent
{
use HasFactory;
protected $guarded = [];
public function penyedia(){
return $this->belongsTo(Penyedia::class, 'penyedia_id');
}
public function user(){
return $this->belongsTo(User::class, 'user_id');
}
}
Here is what I've tried in AdminController:
public function tabelpekerjaan(User $user){
if(Auth::user()->status=='super'){
$pekerjaan = Pekerjaan::with('penyedia')->paginate();
return view('admin.datapekerjaan', compact('pekerjaan'));
}else{
$pekerjaan = $user->pekerjaans;
return view('admin.datapekerjaan', compact('pekerjaan'));
}
}
Here is my code in web.php:
Route::get('/datapekerjaan',[AdminController::class,'tabelpekerjaan'])->name('datapekerjaan');
For now it shows me blank table when I logged in as 'ppk', and what I need is it will shows list of pekerjaan based on the user id. How to achieve this? Here is my table pekerjaans in database:
public function tabelpekerjaan(){
if(Auth::user()->status=='super'){
$pekerjaan = Pekerjaan::with('penyedia')->paginate();
return view('admin.datapekerjaan', compact('pekerjaan'));
}else{
$pekerjaan = Auth::user()->pekerjaans;
return view('admin.datapekerjaan', compact('pekerjaan'));
}
}
Try the above code, i guess your route model binding is in correct.

How to join two model in laravel php

I'm working on a laravel project. I have to join two models Products and User. Where I need to get the results of a product as well as the details of the user who added it. I wrote the code below which isn't working. I'm wondering what'd be the solution.
Can anyone help me in fixing the issue?
Products
class Products extends Model implements AuditableContract
{
use SoftDeletes;
use Auditable;
protected $table = 'products';
protected $fillable = ['product', 'active_ingredient', 'brand', 'similar_to1', 'similar_to2', 'similar_to3', 'similar_to4', 'category_id', 'unit', 'jug_size', 'pallet_qty', 'tote_size', 'class', 'pallet_length', 'pallet_width', 'pallet_height', 'tote_length', 'tote_width', 'tote_height', 'pallet_avg_wt', 'restricted', 'hazmat', 'hazmat_notes', 'market_avg', 'quickbooks_id', 'trending', 'added_by', 'removed_by', 'deleted_at'];
public function productUser()
{
return $this->hasOne('App\User', 'id');
}
}
User
<?php
namespace App;
use Laravel\Passport\HasApiTokens;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use OwenIt\Auditing\Auditable;
use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Authenticatable implements AuditableContract
{
use HasApiTokens, Notifiable;
use SoftDeletes;
use Auditable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
protected $fillable = ['first_name', 'last_name','email','phone','device_token','password','approved','added_by','removed','removed_by','deleted_at'];
public function userProduct(){
return $this->belongsTo('App\Products', 'added_by');
}
}
You need the relation of the Products model to be linked to the user so you create this inside the products model.
You have to modify this:
public function productUser()
{
return $this->hasOne(User::class , 'id', 'added_by');
}
Where user_id is the foreign key in the Products table of the user and id is the primary key in the users table
Then to use that you simple do:
Products::with('productUser')->get();
That will retrieve all products with the user who added each product.
Since you want to retrieve the Products with the user info the function should be written inside the Products model.
The one you have in your user model is irrelevant for what you are trying to achieve so you can remove it.
Product belong to a user and user will have products.
in products
function productUser(){
return $this->belongsTo(User::class, "added_by", "id");
}
in users for one to many relation
function products(){
return $this->hasMany(Product::class, "added_by", "id");
}
if the relation is one on one then it should be like
function product(){
return $this->hasOne(Product::class, "added_by", "id");
}
To get the products with their respective users
$products = Products::whereDate('created_at', Carbon::today())->with('productUser')->get();

Userpermission pivot-function is only accessible via the Auth class

I have a simple Userpermission System consisting of 3 tables: users, permissions and the pivot table permission_user.
This is the User model:
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', '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 permissions()
{
return $this->belongsToMany('App\Permission');
}
}
and here is the Permission Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Permission extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'description', 'level', 'parentpermission',
];
public function users()
{
return $this->belongsToMany('App\User');
}
}
Now when I try to get all the permissions of the currently logged in user with this:
$user_permissions = Auth::user()->permissions()->get();
it works without problems.
But when I try to get another Users Permissions like this:
$user_permissions = User::where('id', '=', $userid)->permissions()->get();
I get the following error:
Method Illuminate\Database\Eloquent\Collection::permissions does not exist.
How do I proceed?
I think you're missing first() here, since you can't get relations of a query builder object. Try this :
$user_permissions = User::where('id', '=', $userid)->first()->permissions()->get();
This first() will actually return User object, and then you can load its relations.
simply you can just add first() method to get just one record and get it's permissions, try this:
$user_permissions = User::where('id', '=', $userid)->first()->permissions;
There's no need to use get() method, this will get all the user permissions directely
Do this -
$user_permissions = User::find($userid)->permissions()->get();

Default User model and Relatinship - Laravel 5.4

I use the default User model and I have created a UserStatus model:
User
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function status()
{
return $this->belongsTo('App\UserStatus');
}
}
UserStatus
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserStatus extends Model
{
public $timestamps = false;
public function users()
{
return $this->hasMany('App\User');
}
}
I cant access to the related model attribute because the $user->status is NULL:
$users = User::all();
foreach ($users as $user) {
var_dump($user->status->name);
}
What is the best practice/solution?
Thanks!
Your query will cause you the N+1 query problem.
Try this which is efficient
$users = User::with('status')->get();
foreach ($users as $user) {
logger($user->status->name);
}
There are two ways to approach:
Simply add a defense condition:
$users = User::all();
foreach ($users as $user) {
if(!empty($user->status))
var_dump($user->status->name);
}
You define a nullable column as user_status_id in your users table and make it foreign key for id in user_status table and create relationship in your User model : hasOne and give the foreign key and then only take users out which are having some status otherwise dont:
$users = User::whereNotNull('user_status_id')->get();

Laravel Relationships - access input from other table

I cant get this working. This should be easy, but I cant figure out how to access a users gamer tag from different table using relationships.
Here is my User.php Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'gamertag', 'slug', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
];
// A user has many messages (Chat)
public function chat () {
return $this->hasMany('App\Chat');
}
}
Here is my Chat.php Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Chat extends Model {
protected $table = "chat";
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'message', 'user_id'
];
// A Chat (or message) belong to a user
public function user() {
return $this->belongsTo('App\User');
}
}
And this is how I;m retrieving the messages:
class HomeController extends Controller {
public function index () {
$messages = Chat::orderBy('created_at', 'desc')->get();
return view('layouts.index', compact('messages'));
}
}
Why Im I having trouble getting the gamer tag to display?
#foreach($messages as $message)
<a class="author">{{ $message->user->gamertag }}</a>
#endforeach
/***** Edit***/
This works:
{{ dd($message->user->gamertag) }}
// This does NOT
{{ $message->user->gamertag }}
Try to use eager loading:
$messages = Chat::orderBy('created_at', 'desc')->with('user')->get();
I figured it out! Everything was working here, its just in my chat table, I had inserted a message with no identified user, so user_id = 0, and it was throwing that error off. Silly mistake.

Categories