2013-07-05 4 views
4

У меня есть 2 модели, контакты и электронная почта. Любой контакт может иметь несколько адресов электронной почты, поэтому я создал отношения один-ко-многим в моделях:Использование laravel, как мне создать представление, которое обновит отношения «один ко многим»?

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'); 
    } 

} 

Надеюсь, я на правильном пути, до сих пор ...

Я уже использовали строительные леса Джеффа Way для контактной модели, поэтому у меня есть этот метод обновления в контроллере:

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.'); 
} 

Кроме того, я изменил вид редактирования, чтобы показать все сообщения электронной почты, связанные с контактом, и затем дополнительный пустой ввод для добавления нового:

@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 

Теперь я понятия не имею, как изменить способ обновления, чтобы обновить электронные письма (если они были изменены) и добавить новый (если введено). Я был бы признателен, если бы кто-нибудь мог указать мне в правильном направлении - спасибо!

+0

Вы можете использовать 'толчок()' метод для сохранения модели и отношений [ссылка] (http://laravel.com/docs/ eloquent # insert-update-delete) –

+0

Спасибо, это может быть в правильном направлении, я не уверен - но мне определенно нужна дополнительная помощь. Как мне обновить соответствующие строки в таблице электронной почты и добавить один, если он еще не существует? – PollenBrands

ответ

4

Ответ на этот вопрос не обязательно является конкретным ответом на Laravel.

Независимо от того, что вам нужно обрабатывать синхронизации электронной почты контакта на с тем, что представлено в виде:

Две тактики:

  1. Удалить все сообщения электронной почты, связанные с контактом. Затем создайте новые письма на основе того, что находится в форме. Таким образом, вы всегда вставляете новые письма.
  2. Получить все электронные письма, связанные с контактом. Итерации через них. Если идентификатор отправленного письма (из формы) соответствует существующей электронной почте, обновите этот адрес электронной почты. Если новое письмо (не имеет идентификатора, связанного с ним), создайте новый. Этот вариант, вероятно, требует вложенного цикла, и его технически следует недооценивать, однако для небольшого количества электронных писем это не имеет большого значения.

Теперь, чтобы получить Laravel (4) -специфический

Eloquent имеет удобный sync() метод для обработки обновления отношений - однако, я считаю, что это только для многих многих отношениях, и, следовательно, опирается на «оси Таблица".

Eloquent также имеет метод push(), но поскольку я еще не играл с ним, я не уверен, что он «синхронизирует» связанные электронные письма за кулисами или просто добавляет новые отношения. Это ваш лучший выбор.

Я написал к Laravel с просьбой, что, в надежде увидеть ответ SØNN: https://twitter.com/fideloper/status/353303438664278018

Для варианта 1:

Во-первых, переименовать все текстовые поля электронной почты (будь то новый или существующий) в email[]. Мы не будем заботиться об их идентификаторе, так как они удаляются.

@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 Примечание: Вы, возможно, придется позаботиться о идентификатору TextField, вероятно, с помощью переменной $key поэтому атрибут метка for="" совпадает с правильной TextField. Я оставлю это до вас.

Затем в PHP вы удалите все письма, связанные с контактом $, а затем создайте их как новые.

// 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); 
} 

Для варианта 2:

Вы будете знать, если новые письма существуют, потому что они не будут иметь идентификатор, связанный с данными из формы. Я хотел бы изменить свои входы, чтобы быть массив писем, так что проще цикл через них:

@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> 

Затем в PHP, для новых писем:

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

Для «не новых» электронных писем, Input::get('email') в моем примере выше, вам, скорее всего, понадобится получить текущие электронные письма, связанные с контактом ($currentEmails = $contact->emails()), и обновить их по мере необходимости в цикле foreach (не выписано здесь).

Нечто подобное должно получить вас на вашем пути, чтобы начать ...