katie hudson
katie hudson

Reputation: 2893

Laravel 5 - setting up relationships

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.

Design

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

Answers (1)

Eduardo Pacios
Eduardo Pacios

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

Related Questions