Can Laravel hasOne be used with belongsToMany? - laravel

Let's say I have two tables:
Users: id, name, country_id
Countries: id, name
Of course each user can only have one country, but each country is assigned to multiple users.
So would it be safe to have a User model that utilizes hasOne and a Country model that uses belongsToMany method?
Documentation makes it seem like you can't mix and match different types of relationships.

What you are describing is actually a One To Many relationship, where one country has many users. Your Country model should utilize a hasMany relationship, while your user would have a belongsTo relationship.

#Andy has already answered well.
Anyway, my advice is to always think in the following way to create a One-To-One, One-To-Many, or a Many-To-Many relationship:
In the table with the foreign key (if any) use belongsTo
In the other table without the foreign key use hasOne or hasMany
In any of them have a foreign key, you have a Many To Many relationship and you must use belongsToMany in both of them (you need the pivot table, of course).

Related

Accessing a secondary relationship from primary model without intermediate table with foreign keys

I have this structure:
model: OrderItem
belongsTo ProductInfo
model: ProductInfo
hasMany OrderItem
hasMany Barcode
model: Barcode
belongsTo ProductInfo
How can I make an easy accessible relationship in the OrderItem to get the Barcodes that match the same product_info_id? The product_infos table is of course not a classic intermediate table containing the foreign keys.
I know this is probably a very simple question since the relationship is also very basic, but I'm kind of confused with all the answers I find online and in the Laravel docs for slightly different situations. F.e. hasManyThrough is not working out in any way here.
This relationship is correct you can access barcode like
$order->ProductInfo->barcodes
This will return an array of barcodes
Instead of using the pivot model, try this.
OrderItem belongs to many Barcode
Then the Barcode model,
table: barcodes
Barcode belongs to many OrderItem
And last create a pivot table
php artisan make:migration create_barcodes_order_items_table and make two columns for foreign_ids, order_item_id and barcode_id.
It would automatically take care of your relationship unless you didn't do anything outside the pattern.
Then you can get all barcodes of order and all orders for a barcode.
$order->barcodes

How to define and use a foreign key as primary key in Laravel?

I have a Users table that can store 8 different types of users. Depending on the user type, I have some other tables with the specific data set for it. So, I would like to use the ID from the Users table as a foreign key and primary key at the same time for those tables. But I am new at Laravel and I don't know how to do that to fit the conventions or, if it is not possible, how to do that when defining my models and one to one relations. Can someone help me? Thanks!
EDIT: Sorry, I think my explanation is not clear enough. Let's say I have 4 tables: users, user_types, customer_organzations, partners, and customers. I would like to use ID, that is PK of users, as a foreign key and primary key for tables customer_organizations, partners and customers, that have different information since they are different type of users in my application but all them login against users table. I don't care user_types table. I think I know how to deal with it.
You haven't given us much in terms of your table structure, so assuming you have a simple one-to-one relationship between a users table and a user_types table, the following would create the required relationship.
In your user_types table migration
$table->foreignId('user_id')->constrained();
The above will add your foreign key to the table and create the relationship back to the users table (this is done 'magically' using conventions so naming is important).
Then in your eloquent models, add the relationships between the models:
User.php
public function type()
{
return $this->hasOne(UserType::class);
}
UserType.php
public function user()
{
return $this->belongsTo(User::class);
}

hasOne or BelongsTo in Laravel?

I have two tables: Photos and ProductPhotos where ProductPhotos is:
ProductPhotos
_______________
product_id | photo_id
And Photos is:
Photos
_______________
id | photo
Does it mean that relation beetween ProductPhotos -> Photos as belongsTo or hasOne yet?
Cause photo_id is foreign key, I guess it is belogsTo
A belongsTo is used to define inverse of the relationship for both hasOne (One to One) and has Many (One to Many) relationship. It would not be possible to tell the relationship with foreign key. You need to define relationship in your relevant model.
In your case, relations can be
ProductPhotos belongsTo Products
Products can have hasOne or hasMany relationship with productPhotos. Depends on the relationship defined on the Product Model
You can have detail understanding on relationship on laravel Docs Relationships
I would set up the relationships with
photos->hasOne->ProductPhotos->belongsTo->Products
Products->hasMany->ProductPhotos->belongsTo->Photos
This will allow for the use of Associate & Disassociate as well as the hasManyThrough relationship
https://laravel.com/docs/5.5/eloquent-relationships#has-many-through
This will also depend on your use of the images of the products
Hope this helps
In this scenario it implies that you have a Products table, so your relationship seems to be from many to many.
Use in both tables:
belongsToMany
https://laravel.com/docs/5.7/eloquent-relationships#many-to-many

Laravel - Database relationships

Let's consider a simple scenario of 'Company' and 'Employee' models.
A company has many employees. Now, when I map this relationship in Laravel, what is the correct approach from the following?
Approach 1:
Employee belongsTo() Company and Company hasMany() Employee
Approach 2:
Company belongsToMany() Employee and Employee hasOne() Company
Basically, what is the difference between belongsTo()-hasMany() and belongsToMany()-hasOne()?
There are three different approaches, in your question you're mixing them up a little. I'll go through all of them.
Many-to-many
A many-to-many relationship would mean, in your example, that a company can have multiple employees and that an employee can work for multiple companies.
So when you're using the belongsToMany() method on a relation, that implies you have a pivot table. Laravel by default assumes that this table is named after both other tables, e.g. company_employee in the example. Both the Company model and the Employee model would then have belongsToMany() relations.
Many-to-one
However, using hasMany() means that it's a one-to-many relationship. If we look at the example again, a company might have many employees but each employee would only be able to be employed by one company.
In the models, that means the Company would have a hasMany() method in its relationship declaration, while the Employee would have a belongsTo() method.
One-to-one
Finally, hasOne() means that it's a one-to-one relationship. What it would mean in your example is that each company may only have one employee. Since the inverse of hasOne() is also belongsTo(), in this scenario, too, every employee could be employed by only one company.
The Company model would then have a hasOne() relationship method, with the Employee having a belongsTo() method.
In practice, you almost always want to construct a database that is as close to reality in its representation as possible. What relationships you use depends on what your case looks like. In the example, I would guess that you want a many-to-one approach, with a foreign key on the employees table, that references the id on the companies table. But ultimately, that's up to you. Hope that helped. :)

Eloquent hasManyThroughOne

Laravel 4.1 introduced the hasManyThrough relationship. This assumes 2 relating hasMany relationships. I however would like to retrieve the hasMany relationships of a belongsTo relationship instead.
Project (id, contact_id, ...)
Contact (id, ...)
Address (id, contact_id, ...)
For each project, I would like to get all addresses.
I managed to do this using a belongsTo() relationship and some additional table joining. However, a belongsTo relationship binds a single object, instead of an array.
So my thoughts are I either need to:
... be able to override the LIMIT 1 behavior on belongsTo relationships
... or be able to override the hasManyThrough to work with a belongsTo as intermediate relationship.
It sounds like you are trying to set up a many-to-many relationship between Projects and Contacts, with a one-to-one relationship between Address and Contact. If that is the case you will need to create a pivot table "project_contact" with columns "project_id" and "contact_id" as well as any other columns (timestamps(), etc). Then you can set a "belongsToMany('Project')" relationship on the Contacts.
I'm not sure if that is what you're after, but it solves the problem as I understand it.

Resources