2013-07-05 67 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'); 
    } 

} 

希望我在正確的軌道上那麼遠,

我以前用過傑夫路的腳手架爲接觸模型,所以我有在控制器此更新方法:

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/方法雄辯#插入更新 - 刪除) –

+0

謝謝,這可能是在正確的方向,我不知道 - 但我絕對需要一些更多的幫助。如何更新電子郵件表中的相應行並添加一個(如果它不存在)? – PollenBrands

回答

4

答案並不一定是Laravel的具體答案。

無論你需要處理與什麼形式提交同步聯繫人的電子郵件內容,:

兩種策略:

  1. 刪除與該聯繫人相關聯的所有電子郵件。然後根據表單中的內容創建新的電子郵件。這樣,你總是插入新的電子郵件。
  2. 獲取與聯繫人關聯的所有電子郵件。通過它們迭代。如果提交的電子郵件(來自表單)的ID與現有電子郵件相匹配,請更新該電子郵件地址。如果電子郵件是新的(沒有與其關聯的ID),請創建一個新的電子郵件地址。這個選項可能需要一個嵌套的循環,並且應該在技術上被忽略 - 但是,對於少量的電子郵件,這不是什麼大不了的事情。現在

,得到Laravel(4)專用

雄辯有一個方便的sync()方法來處理更新的關係 - 不過,我相信這是隻爲多對多的關係,因此,依靠「轉動表」。

Eloquent也有一個push()的方法,但由於我還沒有玩過它,我不確定它是否「同步」幕後的相關電子郵件或只是添加新的關係。這是你最好的選擇。

我啾啾到Laravel問這個,希望能看到一個答案組織神經:https://twitter.com/fideloper/status/353303438664278018

對於選項1:

首先,重命名所有的電子郵件文本框(無論是現有的或新的),以email[]。我們不會關心他們的ID,因爲他們被刪除。

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

小記:您可能必須採取的文本框的ID的照顧,可能使用$key變量,這樣的標籤for=""屬性相匹配,以正確的文本字段。我會留給你的。

然後,在PHP中,您將刪除與$ contact相關聯的所有電子郵件,然後像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); 
} 

選項2:

你就會知道,如果有新的電子郵件,因爲他們不會有與從表格數據關聯的ID。我會改變我的投入是電子郵件的一個數組,所以通過它們來循環更容易:

@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循環中更新它們(此處未寫出)。

類似的東西應該讓你用自己的方式開始...