katie hudson
katie hudson

Reputation: 2893

Laravel 5 handling one to one relationships

I am trying to understand something. I have a projects table which has certain fields. I then have a document table which has a foreign key to a project. To demonstrate, I have the following schemas

Schema::create('projects', function (Blueprint $table) {
    $table->increments('id');
    $table->string('contactName')->default('');
    $table->string('projectName')->default('');
    $table->timestamps();
});

Schema::create('document', function(Blueprint $table)
{
    $table->increments('id');
    $table->longText('documentType')->default('');
    $table->longText('documentContent')->default('');
    $table->integer('projectId')->unsigned()->default(0);
    $table->foreign('projectId')->references('id')->on('projects')->onDelete('cascade');
    $table->timestamps();
});

My projects Model then has the following

public function document()
{
    return $this->hasOne('App\Document', 'projectId');
}

And my document model has the following

public function project()
{
    return $this->belongsTo('App\Project', 'projectId');
}

So a project can have one document. Here is what I am trying to understand. My document is created after the project. So first, I create a project by filling in the form linked to the projects create function. On completion of this, I am then taken to that projects show page. On the show page, I have a form to complete the document

{!! Form::model(new App\Document, 
    [
        'class'=>'form-horizontal',
        'route' => ['document.store', $project->id]
    ]) 
!!}

<div class="form-group">
    {!! Form::label('documentType', 'Document Type:', array('class' => 'col-sm-5 control-label blue')) !!}
    <div class="col-sm-7">
        {!! Form::textArea('documentType', null, array('class' => 'form-control')) !!}
    </div>
</div>
<div class="form-group">
    {!! Form::label('documentContent', 'Document Data:', array('class' => 'col-sm-5 control-label blue')) !!}
    <div class="col-sm-7">
        {!! Form::textArea('documentContent', null, array('class' => 'form-control')) !!}
    </div>
</div>
<div class="form-group">
    {!! Form::submit('Save Data', ['class' => 'btn btn-primary']) !!}
</div>

{!! Form::close() !!}

So that calls the documents store function to save the data to the database.

This all works fine, data is saved as well as the projectId so I am able to link a document to a project. However, if I now visit the show page for that project again, I have an empty form. If I fill in this form, it saves a second row to the database which has the same projectId as the first.

Does this not contradict the one to one relationship if it allows me to create two documents for a project? How am I able to make sure only one document is saved, and next time I visit the show page for a project it might instead have a button to show the document.

Thanks

Upvotes: 0

Views: 95

Answers (1)

Peyman.H
Peyman.H

Reputation: 1952

suppose u do these in order to make the project:

$project = new Project();
$project->contactName = 'something';
$project->projectName = 'somethingElse';
$project->save(); //So you will have the id now!

return redirect()->intended('showPage')->with('project_id'  , $project->id);

So you are redirected to showPage and the projectId is stored in the sessions. Now in the showPage you have another form to make a document. but first retrieve the project U have just created like this:

if(session()->has('project_id')){
    $pId = session('project_id');
    $project = Project::find($pId);
}

now easily use the project for as many document u want! Next we suppose that u registered the document and put the documntId in the session too.

Session::put('documentId' , $document->id);

so in the top of showPage just add some checks:

$result = DB::table('document')
          ->where(['id'=>Session::get('documentId') , 'projectId'=>$project->id])->get();
if($result != null){
// so just show the information not the submit form!
}
else{
 //show the form to submit the document!
}

Upvotes: 1

Related Questions