0
votes

I've got a generic model called Item and a related model called Itemproperties.

Item -> hasOne -> Itemproperties

Itemproperties -> belongsTo -> Item

The Item model has a property called 'itemtype_id' which tells the model which table to store to. Ex: itemtype = 1, then table is itemproperties_1 for itemtype = 2, then table is itemproperties_2.

So I changed the getTable() method on the Itemproperties model:

function getTable(){
    return 'item_properties_' . $this->itemtype_id;
}

So, when creating a new item and its properties, I've been setting up the Itemproperties like this:

// Create & Save the Item
$item = new Item(['itemtype_id' => $itemtype_id]);
$item->save();

// Save the Properties
$itemProperties = new ItemProperties($properties);
$itemProperties->itemtype_id = $item->itemtype_id;
$item->properties()->save($itemProperties);

This seems to work fine... when saving the Itemproperties.

However, when I try to retrieve them, by doing $item->properties, I don't have a way to tell it the itemtype_id, so it can't find the correct table.

My question: Is there a way to set up the eloquent relationship so that I can pass the item->itemtype_id to the Itemproperties so it knows which table to use?

Or is there a better overall strategy to accomplish what I'm doing using different tables for different item types?

1
Okay based on the last question, the first thing that came to my mind is morph i.e polymorphic relationship have you considered this before? laravel.com/docs/5.4/… In anyway you can use this feature?Oluwatobi Samuel Omisakin
Thanks for the suggestion @OmisakinOluwatobi. I don't think that would be a good fit for what I'm doing because I'm going have many different types of items and each one will have a different number and combination of columns.BizzyBob
so if I get you right, you mean the columns in one property differ from the columns in another. say property a has, Z and Y columns, property b can have Z, Y, and K columns?Oluwatobi Samuel Omisakin

1 Answers

0
votes

You shouldn't really need multiple tables to solve this. Having a relationship between Item and Properties should be sufficient. This means in Item model, you should already specify the column to use when building the relationship with Property

public function property()
{
    return $this->hasOne(Property::class, 'itemtype_id', 'itemtype_id')
}

This means the itemtype_id is in the items table, and the assumption here is that itemtype_id in Property model is unique (one - to - one)

Then when you have to save a new properties:

$item = new Item(['itemtype_id' => $itemtype_id]);
$item->save();
//then saving properties
$item->property()->save($properties); //assuming you already have $properties.

The itemtype_id is already passed when building the query and it references. This means if you want to retrieve the properties you just incase you find an item with its type id:

$item = Item::where('itemtype_id', 1)->first();
//get the properties
$properties = $item->property;
//or simply get the properties by calling the Property model directly:
Property::where('item_property', 1)->first();

The only ways I might be wrong is if the fields in your different properties varies and/or I completely misunderstood the question, but generally you don't need multiple tables.