I am creating an webshop app. I have a tech shop with products that are for example CPUs, GPUs, keyboards, mouses etc. All of them have common attributes – id, description, name, but also their own, custom attributes – mouses have dpi and keyboards switch type etc.
What would be the best way to create a database and tables in Laravel?
I tried without inheritance first, but it seems complicated when I want to search a product by id, because I also need to pass product type (table name).
What would be the best approach for this problem?
2
Answers
As one comment has already suggested. Polymorphic relationships are the ideal solution to your requirement.
See docs here
You would want a
productable
relationship to theProduct
as an umbrella to your products holding the shared properties like,description
,price
,stock_level
etc.Build your tables something like:
And your models
Then you can call the product model to get all products with their shared listing details. Then leverage the
productable
relationship to load in their type-specific details.Also, consider having an
Productable
trait on yourMouse
andKeyboard
models to allow you to define shared methods when required.EDIT:
Productable
is probably not the best name for such a trait, maybeHasProductMethods
orIsProduct
Going a step further:
If you then define a
Productable
interface, you can treat yourMouse
andKeyboard
classes asProductable
items. This is really useful when you want to type-constrain your methods parameters but you want methods that can accept aMouse
orKeyboard
instance.For example, you may want to add these items to a basket. The
Basket
would have anaddItem()
method. Instead of having to resolve your relatedProduct
in order to pass aMouse
orKeyboard
instance, your can type-hint theProductable
interface and simply pass theMouse
or `Keyboard.The main model should look something like this:
Then, lets say in GPU model in its fillable you add its attribute that differs the GPU from the main table
You also need this in GPU controller:
For the component migration, you should make attributes like productable_type and productable_id. The key is in using morph like some other comments said.
Then, in GPU controller, your index method should start with something like this: