How to update a pivot table using Eloquent in laravel 5

前端 未结 5 1997
攒了一身酷
攒了一身酷 2020-12-06 09:16

I am new to laravel. I am working on a laravel 5 app and I am stuck here. I have 2 models as such:

class Message extends Eloquent{

    public function user(         


        
5条回答
  •  攒了一身酷
    2020-12-06 09:55

    Laravel 5.8

    First, allow your pivot columns to be searchable by chaining the withPivot method to your belongsToMany

    Copied from my own code to save time

    // I have 3 columns in my Pivot table which I use in a many-to-many and one-to-many-through scenarios
    
    $task = $user->goalobjectives()->where(['goal_objective_id'=>$goal_objective_id,'goal_obj_add_id'=>$goal_obj_add_id])->first(); //get the first record
    
    $task->pivot->goal_objective_id = $new; //change your col to a new value
    
    $task->pivot->save(); //save
    

    The caveat is that your pivot table needs to have a primary 'id' key.

    If you don't want that then you can try the following:

    $tasks=$user->posts()->where(['posts_id'=>$posts_id,'expires'=>true])->get()->pluck('id'); // get a collection of your pivot table data tied to this user
    
    $key=join(",",array_keys($tasks->toArray(),$valueYouWantToRemove));
    
    $tasks->splice($key,1,$newValueYouWantToInsert);
    
    $c = array_fill(0,$tasks->count(),['expires'=>true]); //make an array containing your pivot data
    
    $newArray=$tasks->combine($c) //combine the 2 arrays as keys and values
    
    $user->posts()->sync($newArray); //your pivot table now contains only the values you want
    

    4th July Update Update to above snippet.

    //Ideally, you should do a check see if this user is new
    //and if he already has data saved in the junction table
    //or are we working with a brand new user
    
    $count = $user->goalobjectives->where('pivot.goal_obj_add_id',$request->record)->count();
    
    //if true, we retrieve all the ids in the junction table 
    //where the additional pivot column matches that which we want to update
    
    if($count) {
    
    $ids = $user->goalobjectives->where('pivot.goal_obj_add_id',$request->record)->pluck('id');
    
    //convert to array
    
    $exists = $ids->toArray();
    
    //if user exists and both saved and input data are exactly the same
    //there is no need
    //to update and we redirect user back
    
    if(array_sum($inputArray) == array_sum($exists)) {
    
    //redirect user back
    
    }
    
    //else we update junction table with a private function
    //called 'attachToUser'
    
    $res = $this->attachToUser($user, $inputArray, $ids, $request->record);
    
    }//end if
    
    elseif(!$count) {
    
    //we are working with a new user
    //we build an array. The third pivot column must have equal rows as
    //user input array
    
    $fill = array_fill(0,count($inputArray),['goal_obj_add_id'=>$request->record]);
    
    //combine third pivot column with user input
    
    $new = array_combine($inputArray,$fill);
    
    //junction table updated with 'user_id','goal_objective_id','goal_obj_add_id'
    
    $res = $user->goalobjectives()->attach($new);
    
    //redirect user if success
    
    }
    
    //our private function which takes care of updating the pivot table
    
    private function attachToUser(User $user, $userData, $storedData, $record) {
    
    //find the saved data which must not be deleted using intersect method
    
    $intersect = $storedData->intersect($userData);
    
    if($intersect->count()) {
    
    //we reject any data from the user input that already exists in the database
    
    $extra = collect($userData)->reject(function($value,$key)use($intersect){
    
    return in_array($value,$intersect->toArray());
    
    });
    
    //merge the old and new data
    
    $merge = $intersect->merge($extra);
    
    //same as above we build a new input array
    
    $recArray = array_fill(0,$merge->count(),['goal_obj_add_id'=>$record]);
    
    //same as above, combine them and form a new array
    
    $new = $merge->combine($recArray);
    
    //our new array now contains old data that was originally saved
    //so we must remove old data linked to this user
    // and the pivot record to prevent duplicates
    
    $storedArray = $storedData->toArray();
    
    $user->goalobjectives()->wherePivot('goal_obj_add_id',$record)->detach($storedArray);
    
    //this will save the new array without detaching
    //other data previously saved by this user
    
    $res = $user->goalobjectives()->wherePivot('goal_obj_add_id',$record)->syncWithoutDetaching($new);
    
    }//end if
    
    //we are not working with a new user
    //but input array is totally different from saved data
    //meaning its new data
    
    elseif(!$intersect->count()) {
    
    $recArray = array_fill(0,count($userData),['goal_obj_add_id'=>$record]);
    
    $new = $storedData->combine($recArray);
    
    $res = $user->goalobjectives()->wherePivot('goal_obj_add_id',$record)->syncWithoutDetaching($new);
    
    }
    
    //none of the above we return false
    
    return !!$res;
    
    }//end attachToUser function
    

    This will work for pivot table which doesn't have a primary auto increment id. without a auto increment id, user cannot update,insert,delete any row in the pivot table by accessing it directly.

提交回复
热议问题