笔记:laravel 多对多关联更新sync有bug

Posted by 昆山吴彦祖 on 2018.07.02
namespace App;

use Illuminate\Database\Eloquent\Model;

class MetroStation extends Model
{
    //
	
	protected $guarded = ['id'];
	public $timestamps= false;
	public function metro()
    {
        return $this->belongsTo('App\Metro');
    }
	public function apartment()
    {
		return $this->belongsToMany('App\Apartment','apartment_metro_station','metroStation_id','apartment_id')->withPivot('metro_id', 'distance');
    }
}
$apartment = App\Apartment::find($id);
$s = '[{"metro_id":5,"metroStation_id":1,"distance":959},{"metro_id":5,"metroStation_id":12,"distance":1268}]';	
$apartment->metroStation()->sync(json_decode($s,true));


中间表中现有的数据(apartment_metro_station): 

  apartment_idmetro_id   metroStation_id     distance
 3 5 1 995
 3 5 12 1290

sql执行记录: 

[2018-07-02 07:22:16] select `metroStation_id` from `apartment_metro_station` where `apartment_id` = '3'
[2018-07-02 07:22:16] delete from `apartment_metro_station` where `apartment_id` = '3' and `metroStation_id` in ('12')
[2018-07-02 07:22:16] insert into `apartment_metro_station` (`apartment_id`, `distance`, `metroStation_id`, `metro_id`) values ('3', '959', '1', '5')
[2018-07-02 07:22:16] update `apartment_metro_station` set `metro_id` = '5', `metroStation_id` = '12', `distance` = '1268' where `apartment_id` = '3' and `metroStation_id` = '1'

当关联id(metroStation_id)为1的时候会有这个奇怪的bug,没法被删除。导致数据更新错误。换一个id就不会出现这个问题

正确的sql指令应该是下面这样:

[2018-07-02 07:18:53] select `metroStation_id` from `apartment_metro_station` where `apartment_id` = '3'
[2018-07-02 07:18:53] delete from `apartment_metro_station` where `apartment_id` = '3' and `metroStation_id` in ('12', '12')
[2018-07-02 07:18:53] insert into `apartment_metro_station` (`apartment_id`, `distance`, `metroStation_id`, `metro_id`) values ('3', '959', '1', '5')
[2018-07-02 07:18:53] insert into `apartment_metro_station` (`apartment_id`, `distance`, `metroStation_id`, `metro_id`) values ('3', '1268', '12', '5')

具体原因暂时还不知道,等有时间研究