Laravel eloquent relationships with pivot table - laravel

Hello I have two models User and Car and a pivot table user_car which has two columns user_id and car_id, the combination of the two columns is always unique. Any user can have many cars and one car is assigned to only one user
In the User model I have this
public function cars()
{
return $this->belongsToMany('App\Car', 'user_car');
}
In the Car model I have this
public function user()
{
return $this->belongsToMany(
'App\User', 'user_car', 'car_id', 'user_id'
);
}
$user->cars
returns all the cars for the user as collection which is fine, but I want
$car->user
returns also collection which is only one user. I do not want collection, I want for example to get the user id like this
$car->user->id

Please use laravel default naming convention like alphabetically car_user so that you can follow along. Also it's not a many to many relationship as you've stated in your case it's a one to many relationship. A many to many relationship example something like an author can have many books published and a book can have many authors behind it so in a database table it would be like author_id and book_id in a table
Author_Id | book_id |
1 2
1 1
so in your case it would be like
class User {
public function cars()
{
return $this->hasMany('App\Car');
}
}
make sure you have user_id field in your cars table
and in your Car
class Car{
public function user()
{
return $this->belongsTo('App\User');
}
}
so that you can query it up like
$user = User::first();
$user->car->car_name ;
or when you start w/ car
// to pluck the specific car
$car = Car::find(3);
$car->user->full_name or owner depends upon you

Related

Relationship between user and store

I need to create a relationship between user and many stores. I have created a three models
Store Model
id name email phone info
1 xyz xyz#gmail.com 9329292922 Small Store
2 abc abc#gmail.com 9494949449 Some Store
User Model
id name email
1 ewd ewd#gmail.com
2 xcv xcv#gmail.com
User_Store
user_id store_id
1 1
1 2
What does the user_store model contain relations whether it is belongstoMany or hasmany?
You can use belongsToMany relationship
In your Store model define a method
public function users() {
return $this->belongsToMany(Users::class, 'user_store', 'user_id', 'store_id');
}
In your Users model define a method
public function stores() {
return $this->belongsToMany(Stores::class, 'user_store', 'user_id', 'store_id');
}
Looks to me like you want a simple many-to-many relationship.
For this you only need two models User and Store, you only need StoreUser if you want to do something special with the pivot table otherwise it is unnecessary.
The following would be the Laravel way:
Table structure
stores
id
name
email
phone
info
users
id
name
email
store_user
user_id
store_id
Laravel excepts the pivot table to be called store_user, you can read more about it here:
To define this relationship, three database tables are needed: users,
roles, and role_user. The role_user table is derived from the
alphabetical order of the related model names, and contains the
user_id and role_id columns.
Model structure
class User extends Model
{
public function stores()
{
return $this->belongsToMany(Store::class);
}
}
class Store extends Model
{
public function users()
{
return $this->belongsToMany(User::class);
}
}

How to create relationship in Laravel 5 which will collect records of own model mentioned in pivot table?

I have 3 tables users, companies and pivot table with user_id, company_id.
I can't get users, which belongs to my company inside User model.
Tried like
belongsToMany('App\User','companies_users','company_id','user_id' );
but I get relation with wrong users.
Since you are having a belongsToMany relationship between the User and Company, the User belongs to more than one Company. To get users of the companies of a particular User will not be straight forward. If you are sure that is exactly what you want, then do this:
//inside the User model
public function companies()
{
return $this->belongsToMany('Company');
}
//inside the User model
public function companiesusers()
{
$users= new Illuminate\Database\Eloquent\Collection;
foreach($this->companies as $company)
{
$users = $users->merge($company->users->get());
}
return $users->unique();
}
//inside the Company model
public function users()
{
return $this->belongsToMany('User');
}
Then you can get a user's companiesusers like so:
User::first()->companiesusers();

LARAVEL - How to create an indirect relation between 3 models

I have 3 Models: User, Pet and Clinic.
Let's assume the tables: users, pets and clinics. The relation is, one user can have more than one pet, and one pet only have one clinic.
On the table "Pets" i have a FK to the user_id and another one to the clinic_id.
I want to do something like:
$user->clinics();
on the User model to return all the distinct clinics associated with the user. Now i can only do:
$user->pets()->with('clinics);
but i want to return only the distinct clinics.
User modal:
public function pets()
{
return $this->hasMany('Petable\Models\Pet', 'user_id', 'id');
}
Pet modal:
public function clinic()
{
return $this->belongsTo('Petable\Models\Clinic', 'clinic_id', 'id');
}
Any suggestion ?
The following should be sufficient:
public function clinics()
{
return $this->belongsToMany('Petable\Models\Clinic', 'user_pets')->distinct();
}
And then this allows you to call
$user->clinics();

Laravel Eloquent Relationships - 3 tables, one of which is a lookup table

I am struggling to get my head around some relationships.
I have a Model called User (just stores Users)
A model called Addresses (stores all the addresses a user might have)
A model called Countries (a lookup list of country codes and descriptions)
Below are simplified schema's to help show you what I am trying to achieve:
User model
user_id (integer)
Address Table
user_id (integer)
country_code (integer)
Countries table:
country_code (integer)
country_description (text)
I had a relationship in the User model as follows:
The user model has a relationship:
public function addresses() {
return $this->hasMany('App\Address');
}
In the Address model I have a relationship of
public function user() {
return $this->belongsTo('App\User');
}
Now, in my blade template I am able to #foreach through user->addresses and return the country code stored in the address table, such as 'US' or 'GB'
However, I want to be able to display the full country name, which is held in the Countries table.
How and where do I setup a relationship which will still allow me to iterate through the addresses table, but also have a relationship with the Countries table so that I can display the countries->country_description column.?
Any ideas
Regards
James
In your Address Model:
public function countries()
{
return $this->hasOne('App\Countries', 'country_code');
}
You could then access an $address->countries->country_description;

Laravel BelongsToMany table relation

I have an issue i can't resolve myself with the documentation.
I want to create a very simple conversation system between two users.
I have 3 models and tables:
User
id , name
Conversation
id
Message
id , user_id , conversation_id , content
So a message belongsTo an user and a conversation but then i want the conversation to belongstomany users.
And i dont know how to make this with the tables. If i create a user_id fields in the conversation table i can't have multiple users...
This is definitely in the documentation
Anyways. You're looking for a many to many relationship. For that you need a pivot table (or junction table) that contains the id of a user and the id of a conversation.
Following Laravel convention this table would be called conversation_user and would have the columns id (primary key), conversation_id and user_id
If you have that you can define the relations like this:
User
public function conversations(){
return $this->belongsToMany('Conversation');
}
Conversation
public function users(){
return $this->belongsToMany('User');
}
Querying the relation
$user = User::find(1);
$conversations = $user->conversations;
As documented here for inserting models into a many to many relation you should use attach()
$conversation = new Conversation;
$conversation->users()->attach($idUser1);
$conversation->users()->attach($idUser2);
// or just pass an array of ids
$conversation->users()->attach(array($idUser1, $idUser2));
I would first of all have the three folowig tables:
User
id , name
Conversation_user
user_id , message_id
Message
id , content
Than let's take care of the relationships.
In your User model:
public function conversations()
{
return $this->belongsToMany(Message::class,'conversation_user','user_id','message_id');
}
In your Message model:
public function users()
{
return $this->belongsToMany(User::class,'conversation_user','message_id','user_id');
}
Now you will be able to call the relationship like so:
$user = Auth::user();
$user->conversations();

Resources