Reputation: 2893
everything was working fine with a single Model, but now I am implementing more, I have noticed an issue.
I have several document Models which represent a different type of document. For now, let's say I have DocumentA and DocumentB.
Each Document allows file uploads, so I have created a FileUpload Model. A Document can have many FileUploads.
So, seems pretty straight forward at this point. My FileUpload table has a documentId field, which is a reference to the id field of the Document that is using it.
In DocumentA, I have something like so
public function uploadFile()
{
return $this->hasMany('App\UploadFile', 'documentId');
}
So DocumentA can have many UploadFiles, linked by the documentId.
DocumentB has the same function within its Model.
My problem lies with the UploadFiles model. Firstly, this model now has two belongTo events e.g.
public function documentA()
{
return $this->belongsTo('App\DocumentA', 'documentId');
}
public function documentB()
{
return $this->belongsTo('App\DocumentB', 'documentId');
}
This could be the problem, not sure if I can have multiple belongs to? My immediate problem however is to do with the migration of the doc_file table. At the moment I have this
Schema::table('doc_file', function (Blueprint $table) {
$table->integer('documentId')->unsigned()->default(0);
$table->foreign('documentId')->references('id')->on('document_a')->onDelete('cascade');
});
Schema::table('doc_file', function (Blueprint $table) {
$table->integer('documentId')->unsigned()->default(0);
$table->foreign('documentId')->references('id')->on('document_b')->onDelete('cascade');
});
So I am trying to provide foreign keys to my documents. When I try to migrate, it tells me that
Column already exists: 1060 Duplicate column name documentId
Am I handling my relationships correctly? Essentially, I have many documents, and each document can have many files.
Any assistance with my database relationships appreciated.
Many thanks
Upvotes: 0
Views: 128
Reputation: 5880
Looking at your problem at first glance, it seems that there is a little confusion for you regarding the concept model.
A model is in fact a conceptualization of a real-world object as it is used to represent a real-world entity.
In other words, it represents a whole class of objects with similar properties. For instance a Car model would represent all cars, whether they are of type Lamborghini or Mercedez. The fact is that they all come under the Car classification.
Same concept goes in Eloquent, and with your use case; therefore a Document model is sufficient to represent both of your documents (DocumentA and DocumentB).
To refine what you've achieved so far, your models' relationships can be refactored as such:
Document Model
public function fileUploads(){
return $this->hasMany('App\FileUpload');
}
FileUpload Model
public function document(){
return $this->belongsTo('App\Document');
}
Based on the relationship "EACH document has MANY file uploads", and the inverse "EACH file upload BELONGS to exactly one document", as you can see, there is only one belongsTo()
method in the FileUpload model to define the latter part of the relationship.
Similarly, the schema for the tables defining the above relationship are as follows:
// Schema for Document table
Schema::table('document', function (Blueprint $table) {
$table->increment('id');
$table->string('name', 100);
});
// Schema for FileUpload table
Schema::table('doc_file', function (Blueprint $table) { // file_uploads would have been a more friendly name in my opinion
$table->integer('documentId')->unsigned()->default(0); // note that `documentId` is interpreted as `documentid` in MySQL
$table->foreign('documentId')->references('id')->on('document')->onDelete('cascade');
});
Upvotes: 1