Reputation: 2893
I have been struggling a little with my application and asked a lot of questions, and before I go any further, I just want to make sure that my relationships are ok.
So I am creating an application whereby you can generate different documents based on the input you provide. So, I create a project, and within that project there is a select field which has different types of documents. If I select DocumentA for example, the create form for DocumentA will be displayed to the user. If I choose DocumentB, the create form for DocumentB will be displayed. Now although these forms are different and take different inputs, I wanted a way whereby I would not have to create a new table for every document type. So I came up with the following.
So within a project, I select I want to create DocumentA. I am then displayed the view documentA.create. This view has hidden inputs for the document name and description. The form fields labels are the key in the document_data table, and the value is the input for this field. So, if I create DocumentA, my database might look like this
project
id | projectName |
------------------
1 | Project One |
------------------
document
id | projectId | documentName |
--------------------------------
1 | 1 | DocumentA |
--------------------------------
document_data
id | documentId | key | value |
----------------------------------------------
1 | 1 | clientName | Google |
----------------------------------------------
2 | 1 | projectName | Analytics |
----------------------------------------------
3 | 1 | Contact | Mr Sharp |
----------------------------------------------
4 | 1 | startDate | 29/12/2016 |
----------------------------------------------
Where I am struggling at the moment is that the foreign key documentId is in the document_data table. However, things are only working if I set a foreign key in both of my Models classes e.g.
class Document extends Model
{
protected $table = 'documents';
protected $guarded = [];
public function documentData()
{
return $this->hasMany('App\DocumentData', 'documentId');
}
}
class DocumentData extends Model
{
protected $table = 'document_data';
protected $guarded = [];
public function document()
{
return $this->belongsTo('App\Document', 'documentId');
}
}
If I dont set it in both classes, I get a MethodNotAllowedHTTP exception with no information about it. I have been able to create documents without problem, the problem comes when I need to update. The edit page for DocumentA has a form starting like this
{{ $document }}
{!! Form::model($project->document, [
'class'=>'form-horizontal',
'method' => 'PATCH',
'route' => ['projects.documents.update', $project, $project->document]
]) !!}
Now when I output $document above, I get the correct document that I am working on, as I should do. However, in the update function, if I output $document on its own or if I do
public function update(Request $request, Project $project, Document $document)
{
dd($project->document);
return null;
}
I see both DocumentA and DocumentB. Shouldnt the update only be passed DocumentA?
Why would this be? Any information or advice hugely appreciated.
Many thanks
Upvotes: 0
Views: 47
Reputation: 1865
I think the issue is the relationship between project and document. You probably have document belongsTo project, and project hasMany document, as you can have many documents with projectId = 1. Isn't it? It what I said is okay, when you write $project->document, it brings you all the documents that belong to that project. It's confusing because you named the relationship 'document' instead of 'documents'. You can do 2 things: 1- If each project can have only 1 document, change the relationship in the 'Project' model to hasOne Document. Then, if you do $project->document it will bring you only one. 2- If your app allows a project to have multiple documents, leave the relationship as hasMany (I'd recommend to rename it to documents instead of document), and pass the $document object to the update form, instead of passing the $project and trying to access the document from there. Please let me know if I missed the point of your question and I'm totally wrong
Upvotes: 1