Eloquent Laravel foreign key to spivot table - php

I want to make a foreign key relation to a spivot table in Laravel.
Thats what the schema looks like:
I need to make a relation from the 'roles' table to the spivot table 'organisations_users'.
I want to do this with the column 'role_id' in the 'organisations_users' table.
Now my question is: How do I make this relationship in my models in Laravel. I'm using Laravel Eloquent.
I've already made 2 models 'User' and 'Organisation'.
This is the code:
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that aren't mass assignable.
*
* #var array
*/
protected $guarded = [];
public function organisations(){
return $this->belongsToMany('App\Models\Organisation', 'organisations_users')->withPivot('date_start','date_stop','role_id');
}
}
This is the 'User' model.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Organisation extends Model
{
/**
* The attributes that aren't mass assignable.
*
* #var array
*/
protected $guarded = [];
public function users(){
return $this->belongsToMany('App\Models\User', 'organisations_users')->withPivot('date_start','date_stop','role_id');
}
}
This is the 'Organisation' model.

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.

Laravel 8 belongsTo relationship not returning data on User model

I'm building a Laravel 8 API and want to automatically join user_settings onto a user whenever the User model is queried.
My thinking is that I can achieve this with the belongsTo relationship since user_settings "belongs" to a user.
However, when I attach this to my UserSetting model and query a user I'm not seeing any user settings attached to my User despite having data in the user_settings table.
Where am I going wrong?
Model: User
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class UserSetting extends Model
{
use HasFactory, SoftDeletes;
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'user_settings';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'user_id',
'theme',
'refreshButtonPlacement',
'animationSpeed',
'fetchTimeout'
];
/**
* Get the user that owns the comment.
*/
public function user()
{
return $this->belongsTo(UserSetting::class);
}
}
Model: User
<?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 Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Model;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject
{
use HasFactory, Notifiable, SoftDeletes;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'first_name',
'last_name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password'
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
'last_login_at' => 'datetime'
];
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* #return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* #return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
I also tried using a One To One relationship and defined a settings method on my User model but in Tinker when I ran User::findOrFail(1)->settings; I had nothing either.
Relationship setup:
class User extends Model
{
//some custom stuff
/**
* Get the phone associated with the user.
*/
public function user_setting()
{
return $this->hasOne(UserSetting::class);
}
}
class UserSetting extends Model
{
//some custom things
/**
* Get the user that owns the comment.
*/
public function user()
{
return $this->belongsTo(User::class);
}
}
Afterwards you can use eager laoding by default, in your case you will have to add $with = ['user_setting'] to your User class.
You could also use the ->with() method, for that you will have to use either:
User::with('user_setting')->find(Auth::id());
//or
Auth::user()->with('organisation')->first()
Laravel doesn't load the relationship values in every call because of the obvious overhead. So you will either define the relationship to be loaded by default or you will have to work with the ->with() method for eager loading the relationship.
Add this method to your User model
And you can access the user settings through a dynamic attribute $user-> user_setting
on each User model instance
For more informations
https://laravel.com/docs/8.x/eloquent-relationships#one-to-one
public function user_setting(){
return $this->hasOne(UserSetting::class);
}

Laravel Many to Many relationship only works for first record

I have 2 tables and 1 pivot table with many to many relationship. However the relationship only works for the first record, for the second record onwards, the relationship can't be detected.
These are my tables. Roles, Admins and my pivot table is admin_role.
Model
Admin.php
<?php
namespace App;
use App\Role;
use App\Notifications\AdminResetPasswordNotification;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class Admin extends Authenticatable
{
use Notifiable;
//Send Notification
/**
* Send the password reset notification.
*
* #param string $token
* #return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new AdminResetPasswordNotification($token));
}
/**
* 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',
];
/**
* Relationships
*/
public function role()
{
return $this->belongsToMany(Role::class)->using('App\RoleAdmin');
}
}
Role.php
<?php
namespace App;
use App\Admin;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
public function admin()
{
return $this->belongsToMany(Admin::class)->using('App\RoleAdmin');
}
}
RoleAdmin.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;
class RoleAdmin extends Pivot
{
protected $table = 'admin_role';
protected $fillable = ['admin_id' , 'role_id'];
}
So the problem right now is
$admin = App\Admin::find(1);
$admin->role()->get();
When I run the above method, I can retrieve back record.
Same for this
$role = App\Role::find(1);
$role->admin()->get();
However for this,
$admin = App\Admin::find(2);
$admin->role()->get();
And
$role = App\Role::find(2);
$role->admin()->get();
There are no records.
UPDATE : AdminRoleTable looks like this
id admin_id role_id
1 1 1
2 2 2

Laravel User has only one plan, access that plan with relationship

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 = [
'name','plan_id', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function plan()
{
return $this->hasOne('App\Plan');
}
}
And i have plan_id in user table as a foreign key, that refers to the id in plan table.
When i accesss, User::with('plan')->get(); i cant get plan, what did i miss?
If you have plan_id in user table as a foreign key, that refers to the id in plan table.
<?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 = [
'name','plan_id', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function plan()
{
return $this->belongsTo('App\Plan');
}
}
in your user model :
public function plan()
{
return $this->hasOne('App\Plan','user_id','id');
}
in your controller :
$users=User::with('plan')->get();

How to query in terms of two columns in laravel eloquent orm

I need help to make a query in laravel.
I have three tables
1)Category(Contains id and name column).
2)Geometry(Contains id and name column).
3)practical(Contains id and name column and the Category_id,Geometry_id column/keys )
Now i want to search the practicals in terms of Category_id and Geometry_id.
The Practical.php model file is..
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Model;
use App\Models\Practical;
class Practical extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $table='practical';
protected $fillable = [
'name',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
];
public function category()
{
return $this->belongsTo('App\Models\Category');
}
public function geometry()
{
return $this->belongsTo('App\Models\Geometry');
}
}
The Category and Geometry Model code is
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Model;
use App\Models\Geometry;
class Geometry extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $table='geometry';
protected $fillable = [
'name',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
];
public function practical()
{
return $this->hasMany('App\Models\Practical');
}
}
I know how to query using only one ID.Category or geometry like this..
$Categories=Category::where('id',1)->firstOrFail();
but i failed to query by checking both the ids of Category and Geometry.
Now i want to search the practicals in terms of Category_id and Geometry_id
If you want to search practicals by category ID and geometry ID, just do a simple query:
Practical::where('category_id', $categoryId)
->where('geometry_id', $geometryId)
->get();

Categories