使用 laravel,我如何创建一个将更新一对多关系的视图?

Posted

技术标签:

【中文标题】使用 laravel,我如何创建一个将更新一对多关系的视图?【英文标题】:Using laravel, how do I create a view that will update a one-to-many relationship? 【发布时间】:2013-07-03 01:03:48 【问题描述】:

我有 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');
    


希望到目前为止我在正确的轨道上......

我在 Contact 模型中使用了 Jeff 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

现在,我不知道如何修改更新方法以更新电子邮件(如果已修改)并添加新电子邮件(如果已输入)。如果有人能指出我正确的方向,我将不胜感激 - 谢谢!

【问题讨论】:

你可以使用push()方法来保存模型和关系link 谢谢,这可能是正确的方向,我不确定 - 但我肯定需要更多帮助。我如何让它更新 emails 表中的相应行并在它不存在时添加一个? 【参考方案1】:

这个问题的答案不一定是 Laravel 特定的答案。

无论如何,您需要处理将联系人的电子邮件与表单中提交的内容同步:

两种策略:

    删除与该联系人关联的所有电子邮件。然后根据表单中的内容创建新电子邮件。这样一来,您始终可以插入新电子邮件。 获取与联系人关联的所有电子邮件。遍历它们。如果提交的电子邮件的 ID(来自表单)与现有电子邮件匹配,请更新该电子邮件地址。如果电子邮件是新的(没有与之关联的 ID),请创建一个新电子邮件。此选项可能需要嵌套循环,并且在技术上应该不赞成 - 但是,对于少量电子邮件,这没什么大不了的。

现在,获取 Laravel(4)-specific

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="" 属性与正确的文本字段匹配。我将把它留给你。

然后,在 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-&gt;emails()) 关联的当前电子邮件,并在 foreach 循环中根据需要更新它们(此处未写出) .

这样的事情应该会让你开始……

【讨论】:

以上是关于使用 laravel,我如何创建一个将更新一对多关系的视图?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 php Laravel 中的两个表之间创建一对多关系?

在 Laravel 中同步一对多关系

Laravel 创建和更新具有外部关系的模型

在 laravel 中具有雄辩关系的更新期间从空值创建默认对象

Laravel Eloquent - 保存/更新相关的一对多关系数据

如何使用 laravel 8 同时保存一对多关系数据