I am using my own tables and models for user registration. The goal is that each user can have their user type information. It sounds very simple. For the purposes of the question, I will only show the necessary code.
my model user
looks like this
class User extends Model implements AuthenticatableContract, AuthorizableContract
{
use Authenticatable, Authorizable;
protected $fillable = [
'token',
'active',
];
protected $hidden = [
'password',
];
/**
* Get the Person record associated with the user.
*/
public function person()
{
return $this->hasOne(Person::class, 'id');
}
/**
* Get the User Type record associated with the user.
*/
public function type()
{
return $this->hasOne(Type::class, 'id');
}
}
My model Type
is even simpler at the moment:
class Type extends Model implements AuthenticatableContract, AuthorizableContract
{
use Authenticatable, Authorizable;
protected $fillable = [
'name',
];
protected $hidden = [ ];
/**
* Get the User Type record associated with the user.
*/
public function user()
{
return $this->belongsTo(User::class);
}
}
In one of my controllers, I am sending the information of all users in this way:
public function showAllUsers(Request $request)
{
$users = User::orderBy('id', 'asc')->with('person', 'type')->where('active', 'yes')->get();
return response()->json($users, 200);
}
And the result I get is strange:
[
{
"id": 1,
"token": "userUniqueToken",
"active": "yes",
"persons_id": 3,
"types_id": 1,
"images_id": null,
"created_at": "2021-01-27T06:58:04.000000Z",
"updated_at": "2021-01-27T06:58:04.000000Z",
"person": {
"id": 1,
"name": "Kenny",
"lastname": "",
"phone1": "35555555",
"phone2": "",
"email": "[email protected]",
"created_at": "2021-01-27T06:56:31.000000Z",
"updated_at": "2021-01-27T06:56:31.000000Z"
},
"type": {
"id": 1,
"name": "Empleado",
"created_at": null,
"updated_at": null
}
},
{
"id": 2,
"token": "userUniqueToken",
"active": "yes",
"persons_id": 4,
"types_id": 1,
"images_id": null,
"created_at": "2021-01-27T07:00:11.000000Z",
"updated_at": "2021-01-27T07:00:11.000000Z",
"person": {
"id": 2,
"name": "Josue",
"lastname": "",
"phone1": "35555555",
"phone2": "",
"email": "[email protected]",
"created_at": "2021-01-27T06:57:33.000000Z",
"updated_at": "2021-01-27T06:57:33.000000Z"
},
"type": null
}
]
If I put two, three or four records, only the first one brings all the information of the type of user. Why from the second record the object type
comes empty?
According to what I see in your models, the relationships are wrong, before explaining why, let's see the tables and their fields that you currently have:
Now the reason:
hasOne
(person-type) relationships. That means, starting withperson
, in theory there should be a fielduser_id
for the same relationship "hasOne
", but as we see in your table, the relationship isperson->user
, because in your tableuser
there is a field calledpersons_id
. With this in mind, the correct relationship form in your model would be:Also with
type
the aforementionedbelongsTo
, to your modeluser
, that means that in theory, it is related asuser->type
, but as we see in your table, the relationship is differenttype->user
because in your tableuser
there is a fieldtype_id
, for this reason the correct relationship would behasOne
Now, why does it work for you if it is not correctly related?
id
, which is the primary key in your tables and that is where Laravel sets it. That's why in your results, the first record ofuser
has as a field"persons_id": 3,
but in the relation ofperson
has"person": {"id": 1}
. Because the primary id ofuser
is "1" and ofperson
is "1"