relations on an attribute that can be null in laravel - php

I have an Order model like this :
class Order extends Model
{
protected $primaryKey = 'order_id';
protected $fillable = ['desc', 'date_at', 'status'];
public function creator()
{
return $this->belongsTo(\App\User::class, 'creator', 'user_id');
}
public function validator()
{
return $this->belongsTo(\App\User::class, 'validator', 'user_id');
}
}
In the fields list there is a validator that can be set after creation of an instance of Order model Or not initialized at all.
Since validatior is nullable whenever I want to return an order I got an error like this :
Undefined property: Modules\\Order\\Entities\\Order::$validator

I believe your problem is with the name of the validator function since I assume is a key word in Laravel, try changing the name of the function to something else. and do a composer dump-autoload just in case

Related

why laravel 6 many-to-many relationship does not working?

Hi I simply want to get permissions of the role, I am trying following
$r = Role::find(1);
dd($r->permissions);
The above script does not return any permission however you can see there is data in the below tables. I also tried following but no luck
$role = Role::with('permissions')->where('id', 1)->first();
I have data in the table as you can see
Table:tes_permissions
Table: tes_roles
Table: tes_permission_role
And following are Models
class Permission extends Model
{
protected $table = 'tes_permissions'
public function roles()
{
return $this->belongsToMany('App\Role');
}
}
And
class Role extends Model
{
protected $table = 'tes_roles';
public function permissions() {
return $this->belongsToMany('App\Permission', 'tes_permission_role', 'permission_id', 'role_id');
}
}
Can someone kindly guide me what can be the issue, I would appreciate.
You mixed the order of properties in the belongsToMany(). The third argument is specifying the ID for the model defining the relationship. So change to the following:
public function permissions() {
return $this->belongsToMany('App\Permission', 'tes_permission_role', 'role_id', 'permission_id');
}
And on the Permission model, also define it to be sure.
public function roles()
{
return $this->belongsToMany('App\Role', 'tes_permission_role', 'permission_id', 'role_id');
}

Is there a way to get around using custom route key to load eloquent relationships in laravel

I have two models Product and Images. I changed the route key name on the product model to use the slug field and i'm now unable to load the hasMany relationship with the Image Model
Here is the Product Model
class Product extends Model
{
protected array $with = ['images'];
public function getKeyName()
{
return 'slug';
}
protected array $guarded = [];
public function images() : HasMany
{
return $this->hasMany(Image::class, 'product_id');
}
}
and the Image model
class Image extends Model
{
protected array $guarded = [];
public function image() : BelongsTo
{
return $this->belongsTo(Product::class);
}
}
so when I try
Product::first()->images
it just returns an empty collection
but without overriding the getKeyName() method, everything works fine
getKeyName() will get the primary key for the model. it supports to return id, after you change it to slug, it will return slug
And hasManyHere's the source code ;
The third parameter LocalKey will use getKeyName() when it's empty.
If you still want to use hasMany, you need to pass the third parameter like this:
public function images()
{
return $this->hasMany(Image::class, 'product_id', 'id');
}
This will convert the Eloquent query to database query, which will take the right local key products.id.

Laravel get value from my function in Model

My model Dispatch has a field invoice_id.
It is a foreign key so i can get the invoice details using the below code:
protected $fillable = [
'id',
'truck_no',
'driver_name',
'driver_phone',
'gps_details',
'invoice_id',
];
public function invoice(){
return $this->belongsTo('App\Invoice')->select('id','invoice_no','permit_id');
}
Now I want to get the value permit_id from invoice() so i can use it to get the details of the Permit.
permit_id = id of Permit model
So I use the below code to get the permit data.
public function permit(){
return $this->hasOne('App\Permit','id',$this->invoice()->permit_id);
}
Update:
My Invoice Model has :
class Invoice extends Model
{
protected $fillable = [
'id',
'invoice_no',
'invoice_date',
'permit_id',
];
public function permit(){
return $this->hasOne('App\Permit', 'id', 'permit_id');
}
}
My Permit Model has:
class Permit extends Model
{
protected $fillable = [
'permit_type',
'permit_no',
'application_no',
'supply_unit',
'supply_unit_id' ,
];
public function supplyunit(){
return $this->hasOne('App\SupplyUnit','id','supply_unit_id');
}
}
And as per suggestions i have added below code in my Dispatch Model:
class Dispatch extends Model
{
protected $fillable = [
'id',
'truck_no',
'driver_name',
'driver_phone',
'gps_details',
'invoice_id',
];
public function invoice(){
return $this->hasOne('App\Invoice','id','invoice_id');
}
public function permit(){
return $this->hasOne('App\Permit','id','permit_id');
}
}
But it doesn't work. What should i do to achieve the above? Is there any other solutions please suggest.
Assuming each invoice has one permit, your relationship definition should look like this:
public function permit(){
return $this->hasOne('App\Permit', 'id', 'permit_id');
}
Edit: If invoice belongs to permit, which is the inverse, your relationship would look like this instead:
public function permit(){
return $this->belongsTo('App\Permit', 'permit_id');
}
Edit: Based on your updated question, I think you got the relationship definitions a bit wrong. The following should work:
Since you have an invoice_id column in App\Dispatch, it means that each App\Dispatch belongs to an invoice.
In App\Dispatch, your relationship definition should be as follows:
public function invoice() {
return $this->belongsTo('App\Invoice');
}
// permit does not belong to `App\Dispatch` as a direct relationship
// it should be removed
In App\Invoice, your relationship definition should be as follows:
public function dispatch() {
return $this->hasOne('App\Dispatch');
}
public function permit() {
return $this->belongsTo('App\Permit');
}
In App\Permit, your relationship definition should be as follows:
public function invoice() {
return $this->hasOne('App\Invoice');
}
To then retrieve the permit id from an Invoice model, you would do
$invoice->permit->id;
Change this line
return $this->belongsTo('App\Invoice')->select('id','invoice_no','permit_id');
To
return $this->belongsTo('App\Invoice');
And add the following code on Invoice
public function permit(){
return $this->belongsTo('App\Permit');
}
And you can access as
Dispatch::find($id)->invoice->permit->id;
Or if you want all the information
Dispatch::find($id)->invoice->permit;

Obtaining a list of non-linked models, in many_to_many relations, using Laravel Eloquent

I have a User-Roles model, using Laravel 4 where a user can have many roles, using Eloquent. I can access all roles linked to a user easily using this code :
class User extends Model {
protected $table = 'user';
protected $fillable = array('name');
public function rolesLinked() {
return $this->hasMany('App\UserRoleLink', 'user_id');
}
}
I've been trying to obtain the roles that are not linked to a user, to display on the specific user's page in a select box. Using this function, included in the User class.
public function rolesNotLinked() {
$user = this
$roles = Roles::whereDoesntHave('App\UserRoleLink',function($query) use ($user){
$query->where('user_id',$user->id);
});
}
The problem is, calling this function gives me the following error.
Call to undefined method Illuminate\Database\Query\Builder::App\UserRoleLink()
I've tried using has with < 1 to see if the function was problematic, but after reading this and the online source code, the function call pretty much does what I've tried.
Is something wrong in my function call, or have I messed up configurations somewhere?
For reference, here are my other Model classes:
class UserRoleLink extends Model{
protected $table = 'user_role_link';
protected $fillable = array('role_id','user_id);
public function role() {
return $this->hasOne('App\Role', 'role_id');
}
}
class Role extends Model{
protected $table = 'role';
protected $fillable = array('name');
}
EDIT: I've found out that I messed up by fillables when I copy-pasted. It didn't fix the issue, but I guess that's one step closer.
To use whereDoesntHave method, you must add the relation in your Role Model.
class Role extends Model{
protected $table = 'role';
protected $fillable = array('name');
public function UserRoles() {
return $this->hasMany('App\UserRoleLink', 'id');
}
}
Also, the whereDoesntHave method first parameter is not thte model but the function of the relation:
public function rolesNotLinked() {
$user = this
$roles = Roles::whereDoesntHave('UserRoles',function($query) use ($user){
$query->where('user_id',$user->id);
});
}

Laravel 4, how to access reverse one-to-many relation?

Code:
<?php
class Catering extends \Eloquent {
protected $table = 'catering';
public $timestamps = FALSE;
public function offers() {
return $this->hasMany('Offer', 'cid');
}
}
class Offer extends \Eloquent {
protected $table = 'catering_offer';
public $timestamps = FALSE;
public function catering() {
return $this->belongsTo('Catering');
}
}
I am able to do
$offers = Catering::find(1)->offers;
but, the inverse is not working:
$catering = Offer::find(1)->catering;
is always returning NULL. Database has the right values.
Offer table has 2 columns:
primary(id), int(cid)
that references catering.id.
The question:
How can i access the reverse side of this relation?
You said that, I am able to do
$offers = Catering::find(1)->offers;
and in your Catering model you have
public function offers() {
return $this->hasMany('Offer', 'cid');
}
It seems like you've defined a different foreign key here (cid) to use it instead of the default one that laravel basically supposed to use, so, to do the reverse relation you have to do the same thing in your Offer model's catering function
public function catering() {
return $this->belongsTo('Catering', 'cid');
}
In the Laravel Documentation, it says that, you may override the conventional foreign key by passing a second argument to the hasMany method, like
return $this->hasMany('Offer', 'custom_key');
Same way, to define the inverse of the relationship on the Offer model, you can use the belongsTo method, like
return $this->belongsTo('Catering', 'custom_key'); // cid

Categories