Modelling relationship for a table containing two foreign keys - laravel

I have the following SQL tables for example:
guards
guard_id guard_name guard_type
roles
role_id role_name security_priviledge
guard_roles
gr_id guard_id role_id
How would I define this relationship in Laravel?

You have to define two Models, App/Guard.php and App/Role.php and define their Many to Many relationship. For example:
On App/Guard.php:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Guard extends Model
{
public function roles()
{
return $this->belongsToMany('App\Role');
}
}
On App/Role.php:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
public function guard()
{
return $this->belongsToMany('App\Guard');
}
}

Related

laravel eloquent relationship for indirectly related model

I want a relationship where two unrelated models are linked together with a linker model.
My tables are like:
card table
id(pk)
name
User table
id(pk)
username
password
card_id(fk)
Feature table
id(pk)
name
card_id(fk)
How can i define an eloquent relationship to access all the features of user's card from user model like this:
class User extends Model
{
use HasFactory;
public function features(){
return $this->relatonship_statement;
}
}
and when I tried in Card Model:
class Card extends Model
{
use HasFactory;
public function features(){
return $this->hasMany(Feature::class);
}
}
and in User model:
class User extends Model
{
use HasFactory;
public function card(){
return $this->belongsTo(User::class);
}
public function features(){
return $this->card->features;
}
}
I get error:
App\Models\User::features must return a relationship instance.
What you really want is an accessor function, not a relationship. This is how you would do to achieve what you want.
class User extends Model
{
use HasFactory;
protected $appends = ['features']; //to append features in the response json
public function card(){
return $this->belongsTo(Card::class); //editted User to Card
}
public function getFeatures(){ //accessor method
return $this->card->features()->get();
}
}
sample result after returning user in a controller function
return User::query()->with('card')->first();
However, the right way is to access the features through the Card Relationship because these two models have a direct relationship.

one to many relationship laravel with multiple foreign key

I am on a project with Laravel.
I have two database tables that are in a One-To-Many relationship with each other. They are joined by three conditions. How do I model this relationship in Eloquent?
I am not supposed to modify the database schema, since it has to remain backward compatible with other things.
I have tried the following, but it doesn't work.
The owning side:
use Illuminate\Database\Eloquent\Model;
class Route extends Model
{
public function trips()
{
return $this->hasMany('Trip', 'route_name,source_file', 'route_name,source_file')
}
}
The inverse side:
use Illuminate\Database\Eloquent\Model;
class Trip extends Model
{
public function routes()
{
return $this->belongsTo('Route', 'route_name,source_file', 'route_name,source_file');
}
}
I don't want to use "use Awobaz\Compoships\Compoships;"
You need to give hasMany() and belongsTo method the namespace of your models.
Something like 'App\Models\Trip' or Trip::class
class Route extends Model
{
public function trips()
{
return $this->hasMany('App\Models\Trip', 'route_name,source_file', 'route_name,source_file')
}
}
class Trip extends Model
{
public function routes()
{
return $this->belongsTo('App\Models\Route', 'route_name,source_file', 'route_name,source_file');
}
}

Trying to define a many-to-many relation with a pivot model in Laravel 8

Trying this for hours now and I don't see the error. I have a model 'User' and a model 'Round'. I want to define a n:m-relation with a model 'Flight' as pivot model.
User.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\Image\Manipulations;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class User extends Authenticatable implements MustVerifyEmail, HasMedia
{
use Notifiable;
use InteractsWithMedia;
/*
.....
*/
public function rounds() {
return $this->belongsToMany(Round::class)->using(Flight::class);
}
}
Round.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Round extends Model
{
/*
.....
*/
public function users() {
return $this->belongsToMany(User::class)->using(Flight::class);
}
}
Flight.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\Pivot;
class Flight extends Pivot
{
public $incrementing = true;
/*
.....
*/
}
I made several migrations and seeder.
RelationSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Round;
class RelationSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$round = Round::find(1);
$round->users()->sync([1]);
}
}
When running artisan migrate:refresh --seed all tables are created as expected, but the following error occurs on seeding
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'tour.round_user' doesn't exist (SQL: select * from round_user where round_id = 1)
Obviously Laravel is looking for a standard named pivot-table and not for the desired flights-table.
I am using Laravel 8 in a Docker-Container with Sail.
Where is my mistake?
I found my mistake. With using the pivot model, the name conventions for the intermediate table stay valid. It works with
public function rounds() {
return $this->belongsToMany(Round::class, 'flights')->using(Flight::class);
}
and same thing in the inverse definition
public function users() {
return $this->belongsToMany(User::class, 'flights')->using(Flight::class);
}
Thank you everybody who is helping here - I solved 1000s of problems reading your posts!

How do I make relations laravel in different folders?

My user model like this :
namespace App\Models\Auth;
...
class User extends Authenticatable
{
...
public function vendor()
{
return $this->belongsTo(Vendor::class, 'vendor_id', 'id');
}
}
My vendor model like this :
namespace App\Models;
...
class Vendor extends Model
{
...
public function users()
{
return $this->hasMany(User::class, 'id', 'vendor_id');
}
}
If the relation run, there exist error like this :
Class 'App\Models\Auth\Vendor' not found
It seems that the error occurred because the vendor model is not in the auth folder
How do I solve that error without moving the vendor model to the auth folder?
In simple word, you need to import Vendor class into the User class.
namespace App\Models\Auth;
use App\Models\Vendor; //code to be added
...
class User extends Authenticatable
{
...
public function vendor()
{
return $this->belongsTo(Vendor::class, 'vendor_id', 'id');
}
}
Pretty sure it's because you didn't explicitly load the Vendor class into the User file.
Add into your User file
use App\Models\Vendor;

How to get access to relationship in model User Laravel?

I have default User model:
class User extends Authenticatable implements HasRoleContract
{
use Notifiable, HasRole;
}
With one relationship inside:
public function distributor() {
return $this->hasOne('App\DistributorContacts', 'distributor_id', 'id');
}
So, when user passed authorization I can not see this relation in object:
{{dd(Auth::user())}}
you may use ->with('distributor') on your user Object to get relationships loaded.
e.g.
$user = new User()->with('distributor');
dd($user->distributor);
or
Auth::user()->with('distributor');

Resources