One To Many with pivot not possible. How to redesign relationships? - laravel

I would like to do the following:
Product can have one Supplier. The Supplier contains some data like a name. Additionally there is a pivot-value that should be stored for Supplier that is assigned to Product (e.g. a delivery_service-string).
Example:
Product: A yummy Banana
Supplier: Banana Inc
-> If the Product "A yummy Banana" is supplied by Supplier it should be delivered by DHL. The important thing: You can not add DHL as a field to Supplier, as each Product to Supplier-relation should have it's own delivery-service-field.
As there can be many Products but each Product can only have one Supplier I thought about something like this:
Product
Schema:
- id
- supplier_id
Relation
public function supplier()
{
return $this->belongsTo(Supplier::class);
}
Supplier
Schema:
- id
- name
Relation
public function products()
{
return $this->hasMany(Product::class);
}
This works, but unfortunately I can not store pivot data in the supplier() relation.
At the moment I could imagine to store the value not in a pivot table but in a new row in the Product's schema. But I don't think this is the best way.
Any suggestions? :-)

One item have many childs
This is one-to-many
You need to store item_id in your child table
Item Table
id, name
Child Table
id, item_id, type
If you have a case EG
Each child can have a favorite item then you will have to create a many-to-many relation between them. (Which will be a separate relation)
Create a table "child_item" (pivot)
Child Item Table
child_id, item_id
then create a relation in your laravel
class User extends Model{
...
public function favorites(){
return $this->belongsToMany(Items::class); // Include the path using "use" on top
}
}
So now you get your 2 relations between child and item
One item can have many children
Many children can mark items as favorites

Related

Structuring siblings relation on same model in Laravel

I have student model. I want to add siblings from existing students table on user profile page. I am selecting sibling from a dropdown. Also I want to add the parents of old student(sibling) to the new student(sibling). For student parent I have many-to-many relationship and I am saving student_id and parent_id in pivot table
How can I structure and add this sibling part?
I think the best way to represent this family relations (parents , children , siblings) is to put a nullable parent_id in students table,
so when this parent_id is null this mean that the object is a main parent otherwise it's just a child.
After that you can define some relations :
public function children()
{
return $this->hasMany(self::class, "parent_id");
}
public function parent()
{
return $this->belongsTo(self::class, "parent_id");
}
and for the siblings , I don't know if there is a way to write a relation , but you can return the siblings like so :
$siblings = Student::where("parent_id", $this->parent_id)->get();

How to access multiple model data from an eloquent call

I currently have a product table with the following columns:
id, product_name, product_type, description
I also have three more tables:
medias, attributes, coatings
each of those tables has an id, name, description, img
Each product created din the product table will have multiple, medias, attributes and coatings. To address this I created a table product_relations which contains the columns:
id, product_id, media_id, attribute_id, coating_id
From here I thought I would make a call to product_relations with the product_id and then pull each record so I can access the data. However I'm stuck on how I would do this as an eloquent relationship. Would I do separate has many's in my Product_Relation model like so:
public function media()
{
return $this->hasMany('App\Media');
}
public function attributes()
{
return $this->hasMany('App\Attributes');
}
etc? Or is there a simpler way to build this to access all that at once?

belongsToMany with nullable foreign - Laravel 5.8

in my Laravel project i get this database structure:
Products
Id
Name
Orders
Id
Total
Order_Product
Product_id (nullable)
Order_Id
Details
In my Order model I make belongsToMany retaltionship with Product model:
public function products() {
return $this->belongsToMany(Product::class)->withPivot('Details');
}
The Problem is when I try to get the Order Products Collection
$order->products();
I don't get rows with nullable product_id, Any solution please ? Thank you.
Laravel support "Null Object Pattern" since version 5.5 which allows you to define a default model that will be returned if the given relationship is null.
Try using the following code:
public function products() {
return $this->belongsToMany(Product::class)->withDefault()->withPivot('Details');
}
Most likely, you don't get "nullable" products because you have a relation Order->Products. When you call $order->products(), eloquent tries to get all Product entities that are connected to your Order via product_id field. So, if field is empty, then you can't get Product because there is no connection.
One of the solutions is:
create another entity like OrderLine(Order_Product table); add methods like $orderLine->details() and relation to Product like $orderLine->product()
add relation to OrderLine inside Order - $order->line() or $order->info() etc. -> Order hasMany OrderLine
then use $order->line() to get an order's details and products (if exists)
p.s. I've compiled it in my head so it might need some code adjustments.
Good luck

Laravel 5.5 many to many relationship with an intermediate table

Please help,
I have these relationship in laravel between ITEMS, SUPPLIERS and PURCHASE_ORDERS
As ITEMS and SUPPLIERS has many to many relationship, I created an intermediate table between them, called ITEM_SUPPLIER.
Now I need to make a many to many relationship between PURCHASE_ORDERS and the intermediate table ITEM_SUPPLIER.
How do I make the relationship?
Should I create an intermediate table between them, what's the best way to name it?
Add a model for pivot table ItemSupplier whth extra column id which extends Pivot
use Illuminate\Database\Eloquent\Relations\Pivot;
class ItemSupplier extends Pivot
{
public function purchaseOrder()
{
return $this->belongsToMany(PURCHASE_ORDERS::class, item_supplier_purchase_order);
}
}
As you see you need to create a new item_supplier_purchase_order pivot table and add the relationships
class PURCHASE_ORDERS extends Model
{
public function purchaseOrder()
{
return $this->belongsToMany(ItemSupplier::class, item_supplier_purchase_order);
}
}
Add id column to the item_supplier and create ItemSupplier model for the pivot table. Then create a new item_supplier_purchase_order pivot table and two belongsToMany() relationships between ItemSupplier and PurchaseOrder models.
Also, don't forget to use cascade deleting to delete records from new pivot table when a related record is deleted from item_supplier pivot table.

several tables with many-to-one relationship

I'm using octobercms which uses eloquent models.
I have several tables (Books, Movies, Comics...) and I need to link them to an agegroup table. Every book (movie, comic) gets exactly one agegroup.
My first intention was this:
table agegroup:
id
...
table book:
id
agegroup_id
...
table movie:
id
agegroup_id
...
But I dont get how to put that into an Eloquent model.
Bonus question: there are other similar links (every book, movie etc. has exactly one section) where I need basically the same fields as in the agegroup table: should I reuse that (how?) or create another similar table?
Relationships don't have a single direction, they're two-ways, so one-to-many is the same as many-to-one, only the perspective changes. Meaning that from one perspective a model has many others, and from the other a model belongs to another model. Even the naming used in defining the relationships is very intuitive: hasMany and belongsTo. So here's how you would configure the relationship between a Book model and a AgeGroup model.
A book belongs to only one age group:
class Book extends Model
{
public $belongsTo = [
'ageGroup' => 'Acme\Blog\Models\AgeGroup'
];
}
Then you can get the age group of a book like this:
Book::find(1)->ageGroup->name; // I'm assuming age groups have names
The revers of that relationship is that an age group can have many books associated to it:
class AgeGroup extends Model
{
public $hasMany = [
'books' => 'Acme\Blog\Models\Book'
];
}
Then you can get all books that belong to an age group like so:
foreach (AgeGroup::find(1)->books as $book) {
// access book details like: $book->title;
}
The same logic applies to movies and whatever other entities that can have one age group.

Resources