Relation 3 tables (laravel 5.7) - php

I have 3 table like this image. I want get specify pet with race and get owner of this pet. How can i get all the three records from pets.
I have try
Pets::find($id)->races()->with(users)->get();
public function users()
{
return $this->hasMany('App\User', 'id');
}
public function races()
{
return $this->hasMany('App\Races', 'id', 'id');
}
Thx for help

Usually when you have a [something]_id it indicates the row belongs to another row.
Change the relationships in your Pets model to be:
public function user()
{
return $this->belongsTo('App\User');
}
public function race()
{
return $this->belongsTo('App\Races');
}
Then to get the user and race you can do:
Pets::with('user', 'race')->find($id);
or since you're only getting loading the one Pet here you can simply do:
$pet = Pets::find($id);
and you will have access to $pet->user and $pet->race anyway.

if you have pets model you should add belong to user and also belong to pets_reces in it
and try Pets::find($id)->races;
or Pets::find($id)->users;
another way is to get user id or race id and then get all pets from it with out create model for pets so you can add belong to many in users and races.

Related

Many to Many Relationship with 2 FK referencing from same PK Laravel 8

Hello I am working on a Laravel project, that i have to assign for one Mentorship «Mentoria», one Mentor «Mentor» and one student «Mentorando». The data of the student and the mentor, came from the Users table (i assigned them roles, using Spatie) , and the other table is called «Mentoria» Since there exists a many to many relation i created the pivot table that is called «utilizador_mentoria» and has ID_Mentor, ID_Mentorando (both are FKs coming from the users table),and ID_mentoria (coming from Mentoria table). I defined both models as this:
User Model:
protected $casts = [
'email_verified_at' => 'datetime',
];
public function interesses(){
return $this->belongsToMany(AreaInteresse::class, 'utilizador_interesse', 'id_utilizador', 'id_interesse');
}
public function mentorias(){
return $this->belongsToMany(Mentoria::class, 'utilizador_mentoria', 'id_mentoria', 'id_mentorando', 'id_mentor');
}
ps: I have interesses function with other model, that is working properly. my problem is with the «mentorias»
Mentoria Model:
public function users(){
return $this->belongsToMany(User::class, 'utilizador_mentoria','id_mentor','id_mentorando','id_mentoria');
}
With this, i am trying to get the data from all Mentorias, and the data of the Mentor that is assigned to that that Mentoria, however when i am doing this code on the controller, the data coming from the user appears empty, despite i have the DB filled with data. I tried a echo for testing, and it only shows the data of the Mentoria, and where it should appear the data of the Mentor assigned to that MEntoria, it is empty
the code from the controller:
public function mentorias(){
$mentorias = Mentoria::with('users')->get();
echo $mentorias;
return view('admin/mentorias/admin_mentorias', ['mentorias' => $mentorias]);
}
the output of the echo
[{"id":2,"titulo":"teste","titulo_en":"test","descricao":"fe","descricao_en":"ewfwe","created_at":"2021-12-28T01:32:10.000000Z","updated_at":"2021-12-28T01:32:10.000000Z","users":[]}]
Since as i already said, i already used data from 2 tables with Many to Many relation, however with only 1 FK per PK, and it is working properly, i have no idea why it is not working this way . I already checked for similar questions, however with no luck
Edit:
For testing purposes, i removed the column of one of the two FK that reference from the same PK, and i managed to work, however with this aditional FK i am not managing to make it work . I believe that the problem is with the relation, in the models but i have no idea how to make it work
I rearranged the funcitons in the models as they are now
User Model:
public function mentorias(){
return $this->belongsToMany(Mentoria::class, 'utilizador_mentoria', 'id_mentor', 'id_mentorando', 'id_mentoria');
}
Mentoria Model:
public function users(){
return $this->belongsToMany(User::class, 'utilizador_mentoria','id_mentoria','id_mentorando','id_mentor');
i also tried to took out,example «id_entorando» from the main () and put it after with the «withPivot» method, but it still didn't worked
I don't know if I properly understood the problem but your relationship is not a single "many to many", but two "one to many". In the end I'll show why it's convenient to consider them as two separated relationships.
First: If a user can have multiple mentorships but a mentorship can have only 1 mentor (which I suppose is what's happening), then you should use the "hasMany/belongsTo" pair:
User Model:
public function mentorias(){
return $this->hasMany(Mentoria::class);
}
Mentoria Model:
public function user(){
return $this->belongsTo(User::class);
}
Second: Complete the scenario with the other relationship bewteen the mentorship and the students:
User Model:
public function mentorias(){
return $this->hasMany(Mentoria::class);
}
public function mentoria(){
return $this->belongsTo(Mentoria::class);
}
Mentoria Model:
public function user(){
return $this->belongsTo(User::class);
}
public function mentorandos(){
return $this->hasMany(User::class);
}
There should be a user_id column in the mentorias table that represents the Teacher which the mentorships belong to:
Schema::table('mentorias', function (Blueprint $table) {
$table->unsignedInteger('user_id')->nullable();
});
And there should also be a mentor_id column in the users table that represents the mentorship which the students belong to:
Schema::table('users', function (Blueprint $table) {
$table->unsignedInteger('mentoria_id')->nullable();
});
Third: This double representation of the User Model could lead to confusion, since two different objects (teacher and student) are using the same model but are not meant to have both relationships simultaneously: A teacher shouldn't be mentored and a student shouldn't lead mentorships.
In order to roperly manage Teachers and Students and prevent confusion, you could create additional models that inherit the User Model and define the relationships for them (instead of the User Model), so you can limit the fields and the relationships for each one of them.
User Model:
// No relationships
Teacher Model:
// Extending from User allows you to have all the User Model functionality
class Teacher extends User
{
public function mentorias(){
return $this->hasMany(Mentoria::class)->with('students');
}
}
Student Model:
// Extending from User allows you to have all the User Model functionality
class Student extends User
{
public function mentoria(){
return $this->belongsTo(Mentoria::class)->with('teacher');
}
}
Mentoria Model:
public function teacher(){
return $this->belongsTo(Teacher::class);
}
public function students(){
return $this->hasMany(Student::class);
}
In the end, you'll have all the info you need from the mentorship when you call objects like this:
Teacher::with('mentorias')->get();
// This will show the Teacher's mentorias and the students in each one
Student::with('mentoria')->get();
// This will show the Student's mentoria and its teacher
Mentoria::with(['teacher', 'students'])->get();
// This will show the teacher and the students for each mentoria

Laravel pivot consultation

I need advice about my model relationships,
Logic
Group has many users
Group has many admins
User has many groups (as user)
User has many groups (as admin)
Database Structure
Group Table
User Table
Group_Users table (save id of user and id of group)
Group_Admins table (save id of user and id of group)
Relationship Code
User model
public function groupsUser() {
return $this->hasMany(GroupUser::class);
}
public function groupsAdmin() {
return $this->hasMany(GroupAdmin::class);
}
Group model
public function users() {
return $this->hasMany(GroupUser::class);
}
public function admins() {
return $this->hasMany(GroupAdmin::class);
}
GroupUser model
public function group() {
return $this->belongsTo(Group::class);
}
public function user() {
return $this->belongsTo(User::class);
}
GroupAdmin model
public function group() {
return $this->belongsTo(Group::class);
}
public function user() {
return $this->belongsTo(User::class);
}
Help wanted
Basically as the relationships between users and groups is many to many normally I shouldn't need models of GroupUser and GroupAdmin and then just using sync() function in order to add/remove users and group id's from those tables.
What is my concerns then?
Normally I use that type of connection when I want input bulk ids into database (let say adding tags to posts, suddenly relate 10 tags id to 1 post) that moment using sync() and removing GroupUser and GroupAdmin models makes sense but in my case as users joins/adds to groups one by one, what do you suggest for this relationships?
Is my current approach makes sense?
Is is better if I remove those GroupUser and GroupAdmin models and add them to user, group model like:
public function users()
{
return $this->hasMany(User::class, 'group_users', 'user_id', 'id');
}
and such so?
What do you think is the best practice?
users and groups is many to many
your tables like this?
users, user_group , groups ?
How about use 'belongsToMany' relation?
Laravel many to many relation
// User model
public function groups() {
return $this->belognsToMany(Group::class);
}
// Group model
public function users() {
return $this->belognsToMany(User::class);
}
And use like.
User::find(1)->groups; // return user 1 groups
User::find(1)->groups()->sync($groupIds); // relate user and groups
Group::find(1)->users; // return group 1 users
If you have role column in your users table, you cold add relation like.
// Group model
public function users() {
return $this->belognsToMany(User::class)->where('role', 'the role of normal user');
}
public function admins() {
return $this->belognsToMany(User::class)->where('role', 'the role of admin user');
}
Hope it helps you.

Laravel Eloquent Distant Relationship Setup

I have three tables, a user table, documents table, and a favourites table. The idea is a user can favourite a document, but I can't understand the best way to query this using Eloquent.
User.php
class User extends Authenticatable
{
public function documents()
{
return $this->hasMany('App\Document');
}
public function favourites()
{
return $this->hasMany('App\Favourite');
}
}
Document.php
class Document extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
Favourite.php
class Favourite extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
public function document()
{
return $this->belongsTo('App\Document');
}
}
The favourite table is a simple 2 column table with the user_id and the document_id linking each user to an article they have favourited.
Now I can use a method to get the users favourite articles like so:
App\User::with('favourites')->find(1);
The problem is this brings back the two id's from the favourites table when I want the data from the documents table such as the title and id of the document.
It looks like the "has-many-through" relationship is what I might need to achieve this query, but I'm unsure how to implement it in this use case or even if the "has-many-through" relationship is the correct way to do this?
As your relationship is being setup, you can have a user that has multiple documents, and he can also make multiple documents to be his favorites. So it will always return an array. In order to load all the documents for the user that are his favorites, you can do that the same as you started:
$favoriteDocuments = App\User::with('favourites.document')->find($userId = 1)->get();
// this will contain all the favorite documents for the user, so you can the iterate over them:
foreach($favoriteDocuments as $favoriteDocument)
{
// $favoriteDocument->document; is the object you are looking for.
}
Has many through relationship is used in order to get item from a table to which you don't have access to directly. But to both of your tables you have direct connection to the user.
You are correct with has-many-through, so on User:
return $this->hasManyThrough('App\Document', 'App\Favourite');
And on Document:
return $this->hasManyThrough('App\User', 'App\Favourite');
Eloquent Docs
Your favorites table is a Pivot table. You don't need a favorites model.
User.php
public function favoriteDocuments()
{
return $this->BelongsToMany('App\Document', 'favorite_documents');
}
Now you can call $user->favoriteDocuments to get the users documents.
See the docs about many to many relationships. https://laravel.com/docs/5.7/eloquent-relationships#many-to-many.

Eloquent query not working

I have a many to many relationship between users and categories. In a third table, I have a field called category_id to reference what category each record belongs to. I am setting up a system where by once a user logs in, I want them to see records that has category_id of the categories they've selected when registering.
My code is shown below
I have this relationship setup in users model,
public function categories()
{
return $this->belongsToMany('App\Category');
}
and also this
public function userCats()
{
return $this->categories()->get();
}
in the categories table i have this relationship setup
public function users()
{
return $this->belongsToMany('App\User');
}
in my 3rd Table controller i have the following code
if(Auth::check()){
$servo = Jumong::postOnly()->whereIn('category_id', Auth::user()->userCats())->get();
} else {
$servo = Jumong::all()->where('type','P');
}
dd($servo);
The problem is that the below part,
Auth::user()->userCats()
It returns only the last 2 records in Jumong table and there are more than that.
If I replace it with an array, it will return the right results.
Any ideas on what I am missing?
It doesn't work because whereIn expects an array of ids whereas
Auth::user()->userCats() returns a collection of categories.
You can still doing something like.
Auth::user()->categories->pluck('id')

Models relate in laravel 4

I hope you are well, I need your help, I am working with Laravel and I need to relate information, I have the User, TypeCost and CostCenter models where relationships are:
user:
hasMany ('TypeCost');
belongsTo ('CostCenter', 'id');
TypeCost:
belongsTo ('User');
CostCenter:
hasMany ('User');
I have my view index in the TypeCost module, there are loads information from the cost of each user, I need is that if the user logged belongs to CostCenter one simply show records of users who belong in CostCenter 1 and so CostCenter for the 2, 3, etc.
This is my Index method that is responsible for displaying the list of expenses:
public function index ()
{
$ type_costs = TypeCost :: paginate ();
return View :: make ('type_costs.index' compact ('type_costs'));
}
//for user model
public function costcenter()
{
$this->belongsTo('CostCenter');
}
//for costcenter model
public function users()
{
$this->hasMany('User');
}
//controller function
public function index ()
{
$cost_centers = Auth::user()->costcenter;
$cost_users = $cost_centers->users;
return View::make ('type_costs.index', compact ('cost_users'));
}
it will return list of users that belongs to CostCenter of logged user.
If the field of costcenter_id in user table is nullable, u can add some validation on controller.

Categories