Reputation: 167
Unfortunately, I cannot successfully access a DB column in a pivot table. Besides this, the model is working well.
Model Device
public function tasks()
{
return $this->belongsToMany('App\Task', 'xx', 'yy', 'zz')
->withPivot('id', 'duedate', 'interval', 'reoccurdate', 'completed', 'state')
->withTimestamps();
}
Model Task
public function devices()
{
return $this->belongsToMany('App\Device', 'xx', 'yy', 'zz')
->withPivot('id', 'duedate', 'interval', 'reoccurdate', 'completed', 'state')
->withTimestamps();
}
I tried with a very simple example but failed:
dd(Task::findOrFail(1)->pivot->created_at);
Error:
"Trying to get property of non-object"
Upvotes: 0
Views: 504
Reputation: 7916
You can only access the pivot data if the model collection is the result of a call to the relation method that is aware of that pivot data, meaning you must access devices
on a Task
model to find any pivot data:
$devicesForTask1 = Task::find(1)->devices;
$devicesForTask1->each(function (Device $device) {
// Here we can use pivot, since the models were found through a
// relation method that implements the pivot definition. each
// model now has its own pivot property:
Log::info($device->pivot->duedate);
Log::info($device->pivot->interval);
// etc...
});
This is because of what pivot data represents: additional data that comes with a relationship definition. So created_at
represents a statement such as:
Task
1 belongs to - among many - Device x since created_at
.
Pivot data does not tell you anything about 1 specific model in of itself.
Problem 1:
It is an impossible to determine request to do Task::find(1)->pivot
, since Task
might have multiple belongsToMany
relations, and the expression above does not explicitly specify which relation to access.
Problem 2:
Imagine that Eloquent models would have a cure for problem 1 by implementing a method called pivotFor()
that would let you do something like Task::find(1)->pivotFor('devices')
. Now there is still information missing, because it is not known which of the related Device
models we are trying to access the pivot data for (belongsToMany
queries for a Collection
of many models)
To fix problem 2 our hypothetical pivotFor
method should accept a second argument of type int
, whose value matches the id of the target Device
. But that is just theory. Instead you can try to compose the behavior you're looking for from the facilities that eloquent models, relationships and collections already provide (it's possible), and create this implementation on a higher level (a Support class / repository, for example).
The Laravel documentation provides much more information about how all this works, and it's very likely you'll find a solution there.
in short: You'll need to determine:
Task
Since this is a higher order operation - the belongsToMany
simply does not return single models - you should come up with your own implementation for what you try to achieve.
P.S.
Task::find(1)->devices
returns you exactly Illuminate\Database\Eloquent\Collection|App\Device[]
.
You tried to access created_at
on the pivot object. You should add that to the withPivot call, if that column indeed exists on the pivot table:
public function devices()
{
return $this
->belongsToMany('App\Device', 'xx', 'yy', 'zz')
->withPivot(
'created_at', // Only if created_at exists on the pivot table!
'id',
'duedate',
'interval',
'reoccurdate',
'completed',
'state'
)
->withTimestamps();
}
If you actually intended to get the created_at
value for a Task
or Device
you should access that on the respective model instances directly:
$task = Task::find(1);
Log::info('Task was created at: ' . $task->created_at);
$task->devices->each(function (Device $device) {
Log::info(
'Device '
. $device->id
. ' was created at: '
. $device->created_at
);
});
Upvotes: 1