3

I have a system whereby you can create documents. You select the document type to create and a form is displayed. Data is then added to the form, and the document can be generated. In Laravel things are done via Models. I am creating a new Model for each document but I don't think this is the best way. An example of my database :

Design of database

So at the heart of it are projects. I create a new project; I can now create documents for this project. When I select project brief from a select box, a form is displayed whereby I can input :

  • Project roles
  • Project Data
  • Deliverables
  • Budget

It's three text fields and a standard input field. If I select reporting doc from the select menu, I have to input the data for this document (which is a couple of normal inputs, a couple of text fields, and a date). Although they are both documents, they expect different data (which is why I have created a Model for each document).

The problems: As seen in the diagram, I want to allow supporting documents to be uploaded alongside a document which is generated. I have a doc_upload table for this. So a document can have one or more doc_uploads.

Going back to the MVC structure, in my DocUpload model I can't say that DocUpload belongs to both ProjectBriefDoc and ProjectReportingDoc because it can only belong to one Model. So not only am I going to create a new model for every single document, I will have to create a new Upload model for each document as well. As more documents are added, I can see this becoming a nightmare to manage.

I am after a more generic Model which can handle different types of documents. My question relates to the different types of data I need to capture for each document, and how I can fit this into my design.

I have a design that can work, but I think it is a bad idea. I am looking for advice to improve this design, taking into account that each document requires different input, and each document will need to allow for file uploads.

user4157124
  • 2,809
  • 13
  • 27
  • 42
katie hudson
  • 2,765
  • 13
  • 50
  • 93
  • Does this answer your question? [How can you represent inheritance in a database?](https://stackoverflow.com/questions/3579079/how-can-you-represent-inheritance-in-a-database) – philipxy May 04 '22 at 17:54

4 Answers4

3

You don't need to have a table/Model for each document type you'll create.

A more flexible approach would be to have a project_documents table, where you'll have a project_id and some data related to it, and then a doc_uploads related to the project_documents table.

This way a project can have as many documents your business will ever need and each document can have as many files as it needs.

You could try something like that:

enter image description here

If you still want to keep both tables, your doc_upload table in your example can have two foreign keys and two belongsTo() Laravel Model declarations without conflicts (it's not a marriage, it's an open relationship).

Or you could use Polymorphic Relations to do the same thing, but it's an anti-pattern of Database Design (because it'll not ensure data integrity on the database level).

For a good reference about Database Design, google for "Bill Karwin" and "SQL Antipatterns".

This guy has a very good Slideshare presentation and a book written about this topic - he used to be an active SO user as well.

Alexander Trauzzi
  • 7,277
  • 13
  • 68
  • 112
Rafael Beckel
  • 2,199
  • 5
  • 25
  • 36
1

ok.

I have a suggestion..you don't have to have such a tight coupling on the doc_upload references. You can treat this actually as a stand alone table in your model that is not pegged to a single entity.. You can still use the ORM to CRUD your way through and manage this table..

What I would do is keep the doc_upload table and use it for all up_load references for all documents no matter what table model the document resides in and have the following fields in the doc_upload table

documenttype (which can be the object name the target document object)

documentid_fk (this is now the generic key to a single row in the appropriate document type table(s)

So given a document in a given table.. (you can derive the documenttype based on the model object) and you know the id of the document itself because you just pulled it from the db context.. should be able to pull all related documents in the doc_upload table that match those two values.

You may be able to use reflection in your model to know what Entity (doc type ) you are in.. and the key is just the key.. so you should be able.

You will still have to create a new model Entity for each flavor of project document you wish to have.. but that may not be too difficult if the rate of change is small..

You should be able to write a minimum amount of code to e pull all related uploaded documents into your app..

DaveTheRave
  • 463
  • 2
  • 5
1

You may use inheritance by zero-or-one relation in data model design.
IMO having an abstract entity(table) called project-document containing shared properties of all documents, will serve you.

project-brief and project-report and other types of documents will be children of project-document table, having a zero-or-one relation. primary key of project-document will be foreign key and primary key of the children.
Now having one-to-many relation between project-document and doc-upload will solve the problem.
I also suggest adding a unique constraint {project_id, doc_type} inside project-document for cardinal check (if necessary)
enter image description here

Mohsen Heydari
  • 7,256
  • 4
  • 31
  • 46
1

As other answers are sort of alluding to, you probably don't want to have a different Model for different documents, but rather a single Model for "document" with different views on it for your different processes. Laravel seems to have a good "templating" system for implementing views:

http://laravel.com/docs/5.1/blade

http://daylerees.com/codebright-blade/

Jeff Y
  • 2,437
  • 1
  • 11
  • 18