hasOne and belongsTo relation tables in laravel - laravel

my tables :
users :
id fname email
brands:
id title user_id_made
each brand has a user_id_made that is a foreign key of users table.
in Brand model :
public function user()
{
return $this->hasOne('App\Models\User','id');
}
in User model:
public function brand()
{
return $this->belongsTo('App\Models\Brand','user_id_made');
}
I have a list of brands like this :
title of brand - email of user that made it
in my controller I write this code :
$data['brands'] = Brand::with('user')->simplePaginate(2);
in foreach of view I got trying to get non-object property error :
#foreach($brands as $brand)
<tr>
<td>{{$brand->title_fa}}</td>
<td>{{$brand->title_en}}</td>
<td>{{$brand->user->fname}}</td> // error line

This will give the brand title and email of the user with this brand.
$brands=Brand::with('user')->get();
foreach($brands as $brand)
{
print_r($brand->title);
print_r($brand->user->email);
}
The relation in Brand Model:
public function user()
{
return $this->hasOne('App\Models\User','user_id_made');
}

You have used the wrong relationship. hasOne is used on one-to-one relationships but it should be a one-to-many relationship between your Brand and User. (Each brand is made by one user and each user can make more than one brand)
If you state that a Brand hasOne User, Laravel will assume the users table having a foreign key referencing the brands table.
Instead, modify your relationship method to use belongsTo.
public function user() {
return $this->belongsTo('App\Models\User', 'user_id_made');
}

Since Brand model has the foreign key, this is the side that the
belongsTo() method should be.
If you used the convention when naming your foreign key user_id things would
be more straight forward.
But if for whatever reason you need to have user_id_made name for the column,
this is what you should pass as a second argument in both sides of the relationship.
The User should have the hasOne('App\Brand', 'user_id_made').
And the Brand should have belongsTo('App\User', 'user_id_made').
https://laravel.com/docs/5.3/eloquent-relationships

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);
}
}

Laravel 5.8 Eloquent Model Relationship error

I have a relationship between two models, User and Follower.
User hasMany Follower, and Follower belongsTo User.
In my followers table in the database I have two columns, follower_id and following_id. Both these columns refer to the id column in the users table.
My follower and users table
followers
id
follower_id
following_id
users
id
name
username
User Model
public function followers(){
return $this->hasMany('App\Follower', 'follower_id');
}
public function followings(){
return $this->hasMany('App\Follower', 'following_id');
}
Follower Model
public function user(){
return $this->belongsTo('App\User');
}
In a test controller I am doing this:
$followed = Follower::find(2);
From here, I would like to select one of the columns, follower_id or following_id, and access the user that this particular row belongs to by using $followed->user->name. How would I go about that? Since I need to select a column before accessing, I am a little bit confused.
What can I do to access the data I need?
Your table should be :
followers
id
follower_id
following_id
user_id
users
id
name
username
In your Follower model :
public function user()
{
return $this->hasMany(Follower::class, 'user_id');
}
In your User model :
public function follower()
{
return $this->belongsTo(User::class, 'user_id');
}
Then you can query like this :
$follower = Follower::with('user')->findorFail(2);
$user_name = $follower->user->name;

How to create proper relationships?

I have two types of users: Personal and Business. Personal user can belong to Business user. Thats what i created pivot table personal_users_business_user that have user_id,business_user_id.
I have User,PersonalUser and BusinessUser model.
In User model i have this relationship:
public function company()
{
return $this->belongsToMany('App\Models\PersonalUser','personal_users_business_users', 'user_id', 'business_user_id');
}
Im using attach() method :
$user->company()->attach($business_user_id);
It store data in pivot table. Now what i want in view is something like this:
<input class="typeahead form-control" type="text" name="user_company" #if($user->company->approved == 0) ? disabled : '' #endif value="{{$user->company->company_name}}">
But i dont how how to access to those fields from user in pivot table. Any suggestion?
If you need that Business user have multiple personal users, you should use hasMany, belongsTo relationship. In your BusinessUser model you should create method:
public function personalUsers() {
return $this->hasMany(PersonalUser::class);
}
And in your PersonalUser model you should define this method:
public function businessUser() {
return $this->belongsTo(BusinessUser::class);
}
In your migration, for personal users table add following field:
$table->integer('business_user_id')->unsigned()->nullable();
That will make your code right. You don't need pivot table for that relationship.
Set relationship like this
public function company()
{
return $this->belongsToMany('App\Models\PersonalUser','personal_users_business_users', 'user_id', 'business_user_id')
->withPivot(['your_pivot_column']);
}
And now when you code
$user = User::with(['company'])->get();
$user will have the company relationship with the intended pivot column.

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