Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/288.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
如何将此Laravel PHP代码简化为一个雄辩的查询?_Php_Mysql_Database_Laravel_Eloquent - Fatal编程技术网

如何将此Laravel PHP代码简化为一个雄辩的查询?

如何将此Laravel PHP代码简化为一个雄辩的查询?,php,mysql,database,laravel,eloquent,Php,Mysql,Database,Laravel,Eloquent,我假设这一切都应该在一个查询中,以防止数据库中出现重复数据。这是正确的吗 如何将此代码简化为一个雄辩的查询 $user = User::where( 'id', '=', $otherID )->first(); if( $user != null ) { if( $user->requestReceived() ) accept_friend( $otherID ); else if( !$user->requestSent() )

我假设这一切都应该在一个查询中,以防止数据库中出现重复数据。这是正确的吗

如何将此代码简化为一个雄辩的查询

$user = User::where( 'id', '=', $otherID )->first();

if( $user != null )
{
    if( $user->requestReceived() )
        accept_friend( $otherID );
    else if( !$user->requestSent() )
    {
        $friend = new Friend;
        $friend->user_1= $myID;
        $friend->user_2 = $otherID;
        $friend->accepted = 0;
        $friend->save();
    }
}

您可以使用
firstOrCreate
/
firstOrNew
方法()

示例(来自文档):


使用“firstOrCreate”它将执行与手动相同的操作

从Laravel手册中复制的Firstor或Create的定义

firstOrCreate方法将尝试使用给定的列/值对定位数据库记录。如果在数据库中找不到该模型,将插入具有给定属性的记录

因此,根据这一点,您应该尝试:

$user = User::where( 'id', '=', $otherID )->first();
$friend=Friend::firstOrCreate(['user_id' => $myId], ['user_2' => $otherId]);    

如果不存在,它将检查两个ID,然后在friends表中创建记录。

我想说,如果
用户
朋友
之间存在关系,您可以简单地使用Laravel的模型关系,例如:

$status = User::find($id)->friends()->updateOrCreate(['user_id' => $id], $attributes_to_update));
这就是我要做的,以确保更新新数据或创建新数据

注:我仅在Laravel 5.2.*上使用了updateOrCreate()。另外,在更新之前对用户是否存在进行一些检查也会很好,否则可能会为null抛出一些错误

更新


我不知道该怎么办。你能再解释一下我该怎么做吗?$attributes\u to\u更新怎么样

好的。根据friends表中的哪些字段标记这两个朋友,现在使用您的示例
user_1
user_2
。根据我给出的示例,
$attributes\u to\u update
将是(假设
otherID
是新朋友的id):

如果正确设置了
User
Friend
之间的关系,则
User\u 1
将已包含在插入中

此外,在这个updateOrCreate函数上:

updateOrCreate($attributes_to_check, $attributes_to_update);
$attributes\u to\u check
意味着在创建/更新新字段之前,您要检查这些字段是否已经存在,因此如果我想确保在
接受时进行检查
0
则我可以传递这两个字段,比如说“['user\u 1'=>1,'accepted'=>0]

希望现在情况更清楚

我假设这一切都应该在一个查询中,以防止 数据库中存在重复数据。这是正确的吗

这是不对的。您可以通过在数据库级别上放置
unique
约束来防止重复

如果您的表上没有唯一的键,您可以在php或任何其他语言中做任何事情来防止重复。这是一个简单的事实,如果有人告诉你任何不同的事情,那人是大错特错的。我可以解释原因,但解释会很长,所以我将跳过它

您的代码应该非常简单-只需插入数据。由于不清楚如何处理唯一性(似乎是
user_2,已被接受
,但存在一个边缘情况),如果您没有更多的数据,就不可能提出完整的解决方案

你总是可以忽略我写的内容,尝试使用建议的解决方案,但它们会失败得很惨,最终你会得到重复的解决方案。

我假设这里的“朋友”代表了用户之间的多对多关系。显然,朋友请求是从一个用户(
myID
)到另一个用户(
otherId

你可以用雄辩的语言来表达:

class User extends Model
{
    //...

    public function friends()
    {
        return $this->belongsToMany(User::class, 'friends', 'myId', 'otherId')->withPivot('accepted');
    }
}
也就是说,不需要
Friend
模型

那么,我认为这相当于您想要实现的目标(如果没有,请更新并澄清):

已接受
0或1,根据您的业务逻辑)

sync
方法防止重复插入,并为给定的“myId-otherId”对更新或创建任何行。可以使用此方法在透视表中设置任意数量的其他字段


但是,我也同意在数据库级别设置唯一约束。

对于此类问题,首先,如果您在laravel工作,您必须享受代码和数据库。首先,在数据库和模型中创建表
friend
user
之间的关系。您还必须在数据库中使用
unique

$data= array('accepted' => 0);
User::find($otherID)->friends()->updateOrCreate(['user_id', $otherID], $data));

这是您可以使用的查询。也可以在这里传递多个条件。感谢

重要的是要知道,
first或create
会将信息持久化到数据库并返回实例,而
first或new
只会返回实例而不持久化这就是为什么我会给出注释:)这与我做的不完全相同。您的解决方案不会防止重复。
first或create
将涵盖根据给定的数组,您似乎不理解我想说的内容-不会的。您不能使用PHP或任何其他语言来保证唯一性。这不是处理数据库完整性的方法。
$user->requestReceived()
在做什么?生成的SQL是什么?什么是“防止数据库中的重复数据”在确定“重复”的列上是否有一个
唯一的
索引?可能没有主题,但使用$user=user::find($otherID);而不是$user=user::where('id','=',$otherID)->first();这是否会生成
INSERT。。。在重复密钥更新中…
?@RickJames否。它正在执行
选择*。。。其中user_id=?
。如果未返回任何行-插入新行。否则,更新该行。False——一个单独的线程可能会滑入
SELECT
INSERT
之间,并自行执行
INSERT
,从而把事情搞砸<代码>选择,如果,…
需要一个事务。@RickJames误读了我的评论?我没有写“不需要任何事务”。选择
也可以在事务中,选择
进行更新。否则,
选择
class User extends Model
{
    //...

    public function friends()
    {
        return $this->belongsToMany(User::class, 'friends', 'myId', 'otherId')->withPivot('accepted');
    }
}
$me = User::find($myId);

$me->friends()->syncWithoutDetaching([$otherId => ['accepted' => 0]]);
$data= array('accepted' => 0);
User::find($otherID)->friends()->updateOrCreate(['user_id', $otherID], $data));