我有2个型号,联系人和电子邮件。任何联系人都可能有多个电子邮件地址,因此我在模型中创建了一对多的关系:
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');
}
}
希望到目前为止我走的正确...
我已经将Jeff Way的脚手架用于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 :(得分:4)
答案不一定是特定于Laravel的答案。
无论如何,您需要处理将联系人的电子邮件与表单中提交的内容进行同步:
两种策略:
现在,要获得Laravel(4)特定的
Eloquent有一个方便的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=""
属性与正确的TextField匹配。我会把它留给你。
然后,在PHP中,您将删除与$ contact关联的所有电子邮件,然后像新的一样创建它们。
// 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循环中根据需要更新它们(不是写在这里)。
这样的事情应该让你开始......