Open robsontenorio opened 2 years ago
@robsontenorio Thanks for watching my talk!
I think it's considered a violation since the OrderLine
directly accesses the Product
model which would expose all the properties and functionalities of the Product
model. By accessing the Product
model, the order module would be able to trigger whatever actions against the products table. e.g. update, delete
Also, when you test the order module, you won't be able to create a record for the order_lines
table without creating a product. However, you shouldn't need to know the details of database tables of the inventory module when you are testing the order module so that the order module can be tested independently.
To deal with this, I would create a contract (i.e. interface) in the inventory module and the order module can get the product by calling the method. This will cause an additional DB query but we can keep the modules decoupled.
I really enjoyed your awesome talk during the conference! well done!
I am wondering about the same thing, what if we have a model that is having relationships with many other models in different modules. When using Laravel eager loading "i.e. with method" you will get one collection that have all the related properties of other models.
So using the explained approach in your presentation, does this mean that we need to create a contract in each related module and get the related model information using those services?
@ashourms Thank you for watching the talk!
Basically, a model shouldn't have relationships with models of different modules. If a module needs to get data from different modules, we need to create a contract and get the required data using the contracts (i.e. interfaces). The contract should return a DTO instead of a related eloquent model to avoid exposing all the properties and methods to different modules. Alternatively, a module can dispatch an event and other modules handle it accordingly, which is a more decoupled approach.
If a module needs to get many different data from other modules, you might want to see if there is a better way to define your domain boundaries.
Noted! Thanks for your feedback!
Hi @avosalmon i liked you talk on laracononline of 2year ago. And i face the same problem, i have a Item model in Inventory model that has relation with Account Model (using sales_account_id) in General-Ledger modules.
How can i design the relationship in database of this tables in correct way for modules? Or the database level isn't must relevant at this point, the modularization is on application level Thanks.
TLDR: you will have additional DB query for each line you want to fetch , just like N+1
According its approach models can’t have relationships outside its module.
foreach orderline as line line->product = ProductService::fetch(line->product_id)
@robsontenorio
TLDR: you will have additional DB query for each line you want to fetch , just like N+1
According its approach models can’t have relationships outside its module.
foreach orderline as line line->product = ProductService::fetch(line->product_id)
But should the db structure change?
DB structure is the same. The change is about the fetch N+1 thing.
Thanks
Hi @avosalmon i liked you talk on laracononline of 2year ago. And i face the same problem, i have a Item model in Inventory model that has relation with Account Model (using sales_account_id) in General-Ledger modules.
How can i design the relationship in database of this tables in correct way for modules? Or the database level isn't must relevant at this point, the modularization is on application level Thanks.
@inkomomutane Can I have more context about your modules? What kind of interactions would happen between the modules? The solution depends on the problem you are facing.
Hi @avosalmon i liked you talk on laracononline of 2year ago. And i face the same problem, i have a Item model in Inventory model that has relation with Account Model (using sales_account_id) in General-Ledger modules. How can i design the relationship in database of this tables in correct way for modules? Or the database level isn't must relevant at this point, the modularization is on application level Thanks.
@inkomomutane Can I have more context about your modules? What kind of interactions would happen between the modules? The solution depends on the problem you are facing.
Yap.
I have 2 modules Inventory where are managed all items of purchasing, sales, etc... and every item have transactions account, like sales account, purchasing account like this
+---------------------------------+ | items | +---------------------------------+ | purchase_account_id | | sale_account_id | ....
+-------------------------------+ | accounts | +-------------------------------+ | id ....
But the accounts are managed on General Ledger Module And Items in Inventory module am looking for best approach to design the database schema for that case. Because in your point of view model classes of one module should not have relationships with another outside of.
Nice speak and thanks for sharing!
I got the idea about contracts between modules. But consider this scenario:
The Order module has a OrderLine product_id FK for Inventory and it is great interface usage on your example.
But, by “Laravel way”, to display an OrderLine with product names I would make
OrderLine::with(“product”)->….
It would be a violation ? How do you deal with that ?