Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如果尚未附加,则附加LAVEL关系_Php_Mysql_Laravel_Laravel 5.4 - Fatal编程技术网

Php 如果尚未附加,则附加LAVEL关系

Php 如果尚未附加,则附加LAVEL关系,php,mysql,laravel,laravel-5.4,Php,Mysql,Laravel,Laravel 5.4,如果关系尚未建立,是否有快速建立关系的方法。我正在使用此代码更新模型的关系 if (!empty($request->get('roles')) && is_array($request->get('roles'))) { $message->Roles()->attach($request->get('roles')); } if (!empty($request->ge

如果关系尚未建立,是否有快速建立关系的方法。我正在使用此代码更新模型的关系

        if (!empty($request->get('roles')) && is_array($request->get('roles'))) {
            $message->Roles()->attach($request->get('roles'));
        }
        if (!empty($request->get('users')) && is_array($request->get('users'))) {
            $message->Users()->attach($request->get('users'));
        }
但是我得到了这个错误,我就是这个错误

SQLSTATE[23000]:完整性约束冲突:键“PRIMARY”(SQL:插入到
message\u user
message\u id
user\u id
)值(1,41)、(1,42)、(1,43)、(1,44)、(1,45)、(1,46)、(1,47)、(1,48)、(1,49)、(1,50))的1062个重复条目“1-41”

我希望避免通过一个非常长的数组检查列表来检查哪些用户还没有连接和连接它们。如果这是唯一的办法,也请告诉我

我是这样想的

$message->Users()->attachIfNotAttached($request->get('users'));

类似的方法可能会奏效:

获取已附加的ID:

$attachedIds = $message->Users()->whereIn('id', $request->get('users'))->pluck('id');
从请求阵列中删除附加的ID:

$newIds = array_diff($request->get('users'), $attachedIds);
附上新的身份证:

$message->Users()->attach($newIds);

Laravel对此有内置方法-:


使用
syncWithoutDetaching
sync([arr],false)
看起来代码更干净,但是执行速度比
attach()
慢25倍。这是因为它检查每个id并对每个项执行单独的数据库插入

我建议在您的模型类上扩展eloquent或创建一个新方法

在我的用例中,我有一个
Feed
类和一个
Post
类,它们由多对多枢轴链接。我在Feed类中添加了以下方法

public function attachUniquePosts($ids)
{
    $existing_ids = $this->posts()->whereIn('posts.id', $ids)->pluck('posts.id');
    $this->posts()->attach($ids->diff($existing_ids));
}
  • 使用
    syncWithoutDetaching()
    将20个帖子附加到提要平均需要花费时间 0.107s
  • 使用
    attachuiqueposts()
    平均花费0.004s

MySQL支持
INSERT IGNORE
,但我不认为laravel也支持。我认为唯一的解决方案是在附加之前检查每个用户是否存在关系。在
$request->get('users')
中存储了什么?用户ID?$request->get('users')是用户ID列表的数组,如上面示例中的[41、42、43、44、45、46、47、48、49、50]。这就是我一直在寻找的答案。这是更好的答案。该方法应具有别名,
syncUnique()
或其他名称<代码>无分离同步的效果并不直观。这与OP问题无关,此同步但OP需要attach@behz4d这正是OP想要的。它将请求中的所有用户附加到尚未附加的消息。“WithoutDetaching”部分确保没有未包含在请求中的用户被分离。Laravel的同步方法有一个明显的限制,即它们不支持额外的透视数据,但attach支持。因此,如果您有一个带有额外列的透视表,那么使用
syncWithoutDetaching
并不是一个不合适的选项。相反,您必须遵循接受的答案。是否分离$ids中缺少的元素?
public function attachUniquePosts($ids)
{
    $existing_ids = $this->posts()->whereIn('posts.id', $ids)->pluck('posts.id');
    $this->posts()->attach($ids->diff($existing_ids));
}