pmiranda
pmiranda

Reputation: 8420

Laravel, using pivot table in relations

Laravel 5.3, I have this two models:

User, with this relations:

public function newFunctions()
{
    return $this->belongsToMany('App\NewFunctions', 'user_newfunctions');
}

NewFunctions:

public static function getAllFunctions() {
    $functions = DB::table('new_functions as nf')
    ->select('nf.*')
    ->get();
    return $functions;
}

public function users(){
    return $this->belongsToMany('App\User', 'user_newfunctions', 'new_function_id', 'user_id');
}

(that getAllFunctions was there before I receive this code... don't talk about it, there are a lot of another Controllers using that method... I don't know if its the version or not, but why the hell the old programmer didn't use all() instead )

Then, in my controller I do this:

$user = User::findOrFail($id);

foreach ($user->newFunctions as $key => $function) {
    //dd($function);
    $user_new_functions[] = [$function->id, 69];
}
dd($user_new_functions);

With dd($function); I get this:

NewFunctions {#961 ▼
  #table: "new_functions"
  #connection: null
  #primaryKey: "id"
  #keyType: "int"
  #perPage: 15
  +incrementing: true
  +timestamps: true
  #attributes: array:7 [▶]
  #original: array:9 [▶]
  #relations: array:1 [▼
    "pivot" => Pivot {#962 ▼
      #parent: User {#770 ▶}
      #foreignKey: "user_id"
      #otherKey: "new_functions_id"
      #guarded: []
      #connection: null
      #table: "user_newfunctions"
      #primaryKey: "id"
      #keyType: "int"
      #perPage: 15
      +incrementing: true
      +timestamps: false
      #attributes: array:2 [▼
        "user_id" => 814
        "new_functions_id" => 1
      ]
      #original: array:2 [▶]
      #relations: []

And with dd($user_new_functions); I get:

array:2 [▼
  0 => array:2 [▼
    0 => 1
    1 => 69
  ]
  1 => array:2 [▼
    0 => 3
    1 => 69
  ]
]

What I need is, instead 69 I need to pass the value of function_count that is in the pivot table user_newfunctions

That table is this one:

user_id | new_functions_id | function_count
-------------------------------------------
    814 |           1      |   5
    814 |           3      |   7

So that I will have in dd($user_new_functions); this:

array:2 [▼
  0 => array:2 [▼
    0 => 1
    1 => 5
  ]
  1 => array:2 [▼
    0 => 3
    1 => 7
  ]
]

That array is my goal. Please, any help.

Upvotes: 1

Views: 49

Answers (1)

Tim Lewis
Tim Lewis

Reputation: 29258

You need to include the ->withPivot() method on the relationship:

User.php:

public function newFunctions(){
  return $this->belongsToMany('App\NewFunctions', 'user_newfunctions')->withPivot(['function_count']);
}

NewFunctions.php:

public function users(){
  return $this->belongsToMany('App\User', 'user_newfunctions', 'new_function_id', 'user_id')->withPivot(['function_count']);
}

Now, when querying the relationship, a ->pivot property, containing all the columns from the ->withPivot() method will be available. You can replace the 69 with the following:

$user = User::with(['newFunctions'])->findOrFail($id);
foreach ($user->newFunctions as $key => $function) {
  $user_new_functions[] = [$function->id, $function->pivot->function_count];
}
dd($user_new_functions);

Note: added with(['newFunctions']) for eager loading (potential performance increase, but not required)

The documentation describes how to retrieve intermediate table columns slightly below the "Many to Many" relationship information: https://laravel.com/docs/5.8/eloquent-relationships#many-to-many

Upvotes: 1

Related Questions