How to use laravel, how to create a view that will update the one-to-many relationship?

I have 2 models, contacts and email. Any contact can have multiple email addresses, so I created a one-to-many relationship in the models:

class Contact extends Eloquent { protected $guarded = array(); public static $rules = array( 'first_name' => 'required', 'last_name' => 'required' ); public function emails() { return $this->hasMany('Email'); } } class Email extends Eloquent { public function emails() { return $this->belongsTo('Contact'); } } 

Hope I'm on the right track so far ...

I used the Jeff Way winch for the Contact model, so I have this update method in the controller:

 public function update($id) { $input = array_except(Input::all(), '_method'); $validation = Validator::make($input, Contact::$rules); if ($validation->passes()) { $contact = $this->contact->find($id); $contact->update($input); return Redirect::route('contacts.show', $id); } return Redirect::route('contacts.edit', $id) ->withInput() ->withErrors($validation) ->with('message', 'There were validation errors.'); } 

In addition, I changed the editing view to show all messages related to the contact, and then additional blank input to add a new one:

 @foreach($emails as $key => $email) <li> {{ Form::label('email', 'Email '.$key.':') }} {{ Form::text('email'.$email->id, $email->email) }} </li> @if(count($emails)==$key+1) <li> {{ Form::label('email', 'Email '.($key+1).':') }} {{ Form::text('email'.($email->id+1)) }} </li> @endif @endforeach 

Now I have no idea how to change the modification of the update method in order to update emails (if they were changed) and add a new one (if it is entered). I would appreciate if anyone could point me in the right direction - thanks!

+4
source share
1 answer

The answer to this question is not necessarily a specific answer to Laravel.

Regardless, you need to handle the synchronization of contacts with what is presented in the form:

Two tactics:

  • Delete all letters associated with the contact. Then create new letters based on what is in the form. This way you always insert new letters.
  • Receive all emails associated with a contact. Iterate through them. If the identifier of the sent email (from the form) matches the existing email, update this email address. If a new letter (does not have an identifier associated with it), create a new one. This option probably requires a nested loop, and it should be technically underestimated, but for a small number of emails this does not really matter.

Now, to get Laravel (4) -specific

Eloquent has a convenient sync() method for handling relationship updates, however I find this only for many, many relationships and therefore relies on a “pivot table”.

Eloquent also has a push() method, but since I haven't played with it yet, I'm not sure if it “synchronizes” related emails backstage or simply adds a new relationship. This is your best choice.

I tweeted this with Laravel, hoping to see sonn's answer: https://twitter.com/fideloper/status/353303438664278018

For option 1:

First rename all email text fields (existing or new) to email[] . We will not care about their identifier, since they are deleted.

 @foreach($emails as $key => $email) <li> {{ Form::label('email', 'Email:') }} {{ Form::text('email[]', $email->email) }} </li> @endforeach <!-- No need to have this in PHP logic - always give option to add new emails --> <!-- I'm also assuming you can name multiple new emails, perhaps with some JS --> <li> {{ Form::label('email', 'New Email:') }} {{ Form::text('email[]' }} </li> 

Minor note: You may need to take care of the text field identifier, probably using the $key variable so that the label for="" attribute matches the correct TextField. I will leave it to you.

Then in PHP you will remove all the letters associated with $ contact, and then create them as new.

 // Delete all related emails $contact->emails()->delete(); // I think this works. Otherwise do a manual query or loop through email email and `->delete()` them. // Create new ones foreach( Input::get("emails") as $email ) { $newEmail = new Email; $newEmail->email = $email; $contact->emails()->save($email); } 

For option 2:

You will find out if new emails exist because they will not have an identifier associated with the form data. I would change my inputs to be an array of letters, so it’s easier to iterate over them:

 @foreach($emails as $key => $email) <li> {{ Form::label('email', 'Email '.$key.':') }} <!-- Notice this is an array now: --> {{ Form::text('email['.$email->id.']', $email->email) }} </li> @endforeach <!-- No need to have this in PHP logic - always give option to add new emails --> <!-- I'm also assuming you can name multiple new emails, perhaps with some JS --> <li> {{ Form::label('newemail', 'New Email:') }} {{ Form::text('newemail[]' }} </li> 

Then in your PHP for new emails:

 foreach( Input::get('newemail') as $email) { $newEmail = new Email(); $newEmail->email = $email; $contact->emails()->save( $newEmail ); } 

For "not new" emails, Input::get('email') in my example above, you will most likely need to receive the current emails associated with the contact ( $currentEmails = $contact->emails() ), and Update them as necessary in the foreach loop (not written here).

Something like this should help you get started ...

+4
source

Source: https://habr.com/ru/post/1489818/


All Articles