使用同步在Laravel 4中替换数据透视表记录

时间:2013-12-04 10:22:25

标签: arrays laravel-4 associative-array

编辑:由于clod986的回答已经清除了一些有关sync()方法的内容,我现在修改了我的代码:

public function attachDelegates($eventId, $delegates)
{
    $event = $this->find($eventId);

    foreach ($delegates as $key => $value)
    {
        if( ! $event->delegates->contains($key))
        {
            $event->delegates()->attach($key, array(
                'delegate_status_id'    => $value['delegate_status_id'],
                'price'                 => $value['price'],
                'prerequisites'         => $value['prerequisites'],
                'booking_id'            => $value['booking_id']
            ));
        }
    }
}

我有4张桌子:

事件,委托,未知数和名为delegate_event的数据透视表

在应用程序中,您可以根据您按下的按钮在事件或单个未知代理上存储多个未知代理。

我遇到的问题是,当第一次存储单个未知代理时,它运行良好,但是一旦您尝试存储另一个未知代理,它将在各自的表中存储委托和未知但是当它将委托与delegate_event表上的事件同步,它将替换/更新以前的记录。添加多个未知代表工作正常。

这是我的代码:

// Filename: AdminDelegatesController.php
// Selection: 1
public function store()
{
    $delegateData = Input::except(array('delegate_status_id', 'price', 'event_id', 'account_id', 'amount'));
    $eventId = Input::get('event_id');
    $event = $this->event->find($eventId);
    $amount = Input::get('amount');

    if ( ! empty($amount))
    {
        $message = (object) array(
            'title'         => 'Excellent!',
            'content'       => 'The unknown delegates were successfully added to the event.',
            'alert_type'    => 'success'
        );
        $price = Input::get('price') / $amount;
        $data = array(
            'delegate_status_id'    => Input::get('delegate_status_id'),
            'price'                 => $price,
            'prerequisites'         => 'on'
        );
        $unknowns = array();
        for ($i = 0; $i < $amount; $i++)
        {
            $unknownKey = 'unknown-'.$event->start_date->toDateString().'-'.(int) rand(0,9999);
            $data['key'] = $unknownKey;
            $unknowns[] = $data;
        }
        $unknownData = $this->unknown->storeUnknowns($unknowns);
        $delegates = $this->delegate->storeDelegates(null, $unknownData, $eventId, null);
        $this->event->storeDelegates($eventId, $delegates);
    }
    else
    {
        $message = (object) array(
            'title'         => 'Excellent!',
            'content'       => 'The unknown delegate was added successfully to the event.',
            'alert_type'    => 'success'
        );
        $unknownKey = 'unknown-'.$event->start_date->toDateString().'-'.(int) rand(0,9999);
        $data = array(
            'key'                   => $unknownKey,
            'delegate_status_id'    => Input::get('delegate_status_id'),
            'price'                 => Input::get('price'),
            'prerequisites'         => 'on'
        );
        $unknowns = array($data);
        $unknownData = $this->unknown->storeUnknowns($unknowns);
        $delegate = $this->delegate->storeDelegates(null, $unknownData, $eventId, null);
        $this->event->syncDelegates($eventId, $delegate);
    }
    return Redirect::back()->with('message', $message);
}

// Filename: Unknown.php
// Selection: 1
public function storeUnknowns($unknowns)
{
    if (is_null($unknowns))
    {
        return null;
    }
    foreach ($unknowns as $unknown) {
        $delegate = $this->create(array('key' => $unknown['key']));
        $data[$delegate->id]['delegate_status_id'] = $unknown['delegate_status_id'];
        $data[$delegate->id]['price'] = $unknown['price'];
        $data[$delegate->id]['unknown_id'] = $delegate->id;

        if (empty($unknown['prerequisites']))
        {
            $data[$delegate->id]['prerequisites'] = '0';
        }
        else
        {
            $data[$delegate->id]['prerequisites'] = $unknown['prerequisites'];
        }
    }
    return $data;
}

// Filename: Delegate.php
// Selection: 1
public function storeDelegates($contactData, $unknownData, $eventId, $bookingId)
{
    $delegates = array();
    if (!is_null($contactData))
    {
        foreach ($contactData as $contact)
        {
            $delegate = $this->create(array('contact_id' => $contact['contact_id'], 'unknown_id' => '0'));
            $delegates[$delegate->id]['delegate_status_id'] = $contact['delegate_status_id'];
            $delegates[$delegate->id]['price'] = $contact['price'];
            $delegates[$delegate->id]['prerequisites'] = $contact['prerequisites'];
            $delegates[$delegate->id]['booking_id'] = $bookingId;
        } 
    }

    if (!is_null($unknownData))
    {
        foreach ($unknownData as $unknown)
        {
            $delegate = $this->create(array('contact_id' => '0', 'unknown_id' => $unknown['unknown_id']));
            $delegates[$delegate->id]['delegate_status_id'] = $unknown['delegate_status_id'];
            $delegates[$delegate->id]['price'] = $unknown['price'];
            $delegates[$delegate->id]['prerequisites'] = $unknown['prerequisites'];
            $delegates[$delegate->id]['booking_id'] = $bookingId;
        }  
    }

    return $delegates;
}

// Filename: Event.php
// Selection: 1
public function syncDelegates($eventId, $delegates)
{
    $event = $this->find($eventId);
    return $event->delegates()->sync($delegates);
}

当添加多个未知委托时,生成的$ delegates数组看起来像:

array(3) {
    [1] array(4) {
        ["delegate_status_id"] "2"
        ["price"] 250
        ["prerequisites"] "on"
        ["booking_id"] NULL
    }
    [2] array(4) {
        ["delegate_status_id"] "2"
        ["price"] 250
        ["prerequisites"] "on"
        ["booking_id"] NULL
    }
    [3] array(4) {
        ["delegate_status_id"] "2"
        ["price"] 250
        ["prerequisites"] "on"
        ["booking_id"] NULL
    }
}

同样,这在传递给sync方法时也能正常工作。它将所有正确的委托关系存储在数据透视表中。

当存储单个未知委托时,$ delegates数组看起来像:

array(1) {
    [4] array(4) {
        ["delegate_status_id"] "1"
        ["price"] "3000"
        ["prerequisites"] "on"
        ["booking_id"] NULL
    }
}

同样,这个工作正常但是只要你尝试添加另一个,它就会用新的ID替换/更新记录。

有人能指出我正确的方向吗?感谢。

1 个答案:

答案 0 :(得分:1)

这是Laravel 4的预期行为:在->sync($array)的末尾,您将只拥有数组中的项目。 Check here了解更多详情。

您应该使用不同的方法:检查项目是否在集合中,否则添加它。

public function syncDelegates($eventId, $delegates){
    $event = $this->find($eventId);
    foreach($delegates as $key => $value){
        if(!$event->delegates->contains($value)){
            $event->delegates()->attach($value);
        }
    }
}

这应该添加您缺少的项目