Laravel的hasMany更新关系

3

在laravel中,我有一个hasMany关系,我们称之为fruits。用户只能拥有每种水果的一个,并且在个人资料页面上是一个复选框。目前我有以下代码:

if (!empty($data['fruits'])) {
  $fruits = $data['fruits'];
  foreach($user->fruits as $i) {
    $i->delete();
  }
  for($a=0;$a<count($fruits);$a++)
    {
      $AT = new Fruits;
      $AT->user_id=$user->id;
      $AT->fruit_id=$fruits[$a];
      $AT->save();
    }
}

这段代码的作用是检查水果选择是否为空,如果不为空,则删除与用户相关联的现有水果并创建新的水果。

我觉得这段代码有点丑陋,因为我不确定如何检查该用户是否已存在相应的水果,如果不存在则创建。

如有需要,请提出建议。

Schema::create('user_fruits', function (Blueprint $table) {
    $table->engine = 'InnoDB';
    $table->increments('id');
    $table->integer('user_id')->unsigned();
    $table->integer('fruit_id')->unsigned();
    $table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
    $table->foreign('fruit_id')->references('id')->on('fruits')->onUpdate('cascade')->onDelete('cascade');
    $table->timestamps();
});

你能分享一下你的表迁移user和fruit吗?你需要在表fruit中搜索user_id,如果不存在就创建新的。 - Diego Cespedes
@Diego182 嘿,我已经添加了我的user_fruits表。 - Michael Mano
你是否正在使用数据透视表方法来存储 hasMany 关系? - Md Nozibulla Bashar
@BashartheCoder 上面提到的表是存储多个关系的表,水果表并不存在,只是用来存储水果ID和名称的。上述表格用于保存用户ID和水果信息。 - Michael Mano
我认为人们把这件事想得太深了。我只是想知道一个简单的方法来引用我的user_fruits表,并查看$AT-> fruit_id=$fruits[$a];是否与用户ID存在,否则我可能会将其保留原样,我的意思是删除所有内容并在任何人保存用户配置文件时重新输入可能相当糟糕。 - Michael Mano
我认为你应该使用sync方法进行更新,因为在多对多关联中需要使用sync方法。你可以查看这个教程(https://laracasts.com/series/laravel-5-fundamentals/episodes/23)。你还可以查看第21和22集。我认为这对处理多对多关系会有所帮助。 - Md Nozibulla Bashar
1个回答

0

Eloquent 中一个有趣的缺陷是在 hasMany 关系中没有 sync() 或者与 save() 相反的方法。因此,您必须删除并重新添加。一种不涉及昂贵的多次删除和插入的替代方法是检查每个水果,并仅删除(和添加)必要的水果。我正在密切关注这个问题,如果没有任何结果,我可能会提交 PR 将其添加到 Eloquent。

以下是一种稍微更清晰的方法来完成您已经拥有的内容:

Fruits::where('user_id', $user->id)->delete();

$fruits = [];
foreach ($data['fruits'] as $key => $value) {
    $fruit = new Fruits();
    $fruit->id = $key;
    $fruits[] = $fruit;
}

$user->saveMany($fruits);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接