2017-03-06 4 views
1

내 피벗 테이블 3 열 전체가 포함되어 있습니다. 사용자와 역할을 동기화 할 수 있지만 특정 그룹에 속한 사용자 만 동기화 할 수 있기를 바랍니다.Laravel 피벗 테이블의 일부만 동기화

간단한 동기화 ([1,2,3])를 실행하면 그룹을 모두 무시하고 피벗 테이블의 모든 것을 제거합니다.

옵션 A :

  1. 이 UserRoles에 대한 새로운 모델을 만들기

    내가 마음에 몇 가지 솔루션을 가지고있다.
  2. UserRoles::where('group', '=', '1');
  3. User::roles()->detach(list_of_ids_from_previous_query);
  4. User::roles()->attach(list_of_desired_ids_for_group_1);

옵션 B :

  1. User::roles()->all();
  2. 팬시 $list_of_ids_from_previous_query
  3. User::roles()->sync(list_of_merged_ids);으로 병합 $list_of_desired_ids_for_group_1

Eloquent에서 다른 방법이 있습니까? 나는 ID와 그룹의 2 차원 다차원 배열을 병합 할 필요가 없기 때문에 구현하기 쉽다 (a) 옵션을 구현하는 것이 더 쉽다. 또한 옵션 (a)은 모든 그룹 행에서 DELETE 및 INSERT를 실행해야하기 때문에 데이터베이스 집약적 일 수 있습니다.

답변

1

Laravel sync() 메서드를 모방했지만 일부 추가 필터링이 추가되었습니다. 이 메소드를 리포지토리에 추가했지만 모델로 메소드로 추가 할 수있었습니다.

당신이 모델에 방법을 이동하려는 경우, 당신은 같은 것을 할 수있는 :

/** 
* Simulates the behaviour of Eloquent sync() but 
* only on a specific subset of the pivot 
* @param integer $group 
* @param array $roles 
* @return Model 
*/ 
public function syncBy($group, array $roles) 
{ 
    // $this is the User model for example 
    $current = $this->roles->filter(function($role) use ($group) { 
     return $role->pivot->group === $group; 
    })->pluck('id'); 

    $detach = $current->diff($roles)->all(); 

    $attach_ids = collect($roles)->diff($current)->all(); 
    $atach_pivot = array_fill(0, count($attach_ids), ['group' => $group]); 
    $attach = array_combine($attach_ids, $atach_pivot); 

    $this->roles()->detach($detach); 
    $this->roles()->attach($attach); 

    return $this; 
} 

사용법 :

$user= App\User::find(1); 
// Will sync for user 1, the roles 5, 6, 9 but only within group 3 
$user->syncBy(3, [5, 6, 9]); 
관련 문제