php - Laravel 5 issue with wherePivot -
i working laravel 5 , having issue getting ->wherepivot()
work on many-to-many relationship. when dd()
sql looks eloquent looking records in pivot table `pose_state`.`pose_id` null`.
i hoping simple error , not bug. ideas appreciated.
database structure
pose
id name type
state
id name machine_name
pose_state
pose_id state_id status
models
pose
<?php namespace app; use db; use app\state; use illuminate\database\eloquent\model; class pose extends model { public function states() { return $this->belongstomany('app\state') ->withpivot('status_id') ->withtimestamps(); } public function scopewithpendingreviews() { return $this->states() ->wherepivot('status_id',10); } }
state
<?php namespace app; use illuminate\database\eloquent\model; class state extends model { public function poses() { return $this->belongstomany('pose') ->withpivot('status_id') ->withtimestamps(); } }
posescontroller function
public function listposesforreview(){ $poses = pose::withpendingreviews()->get(); dd($poses->toarray() ); }
sql
select `states`.*, `pose_state`.`pose_id` `pivot_pose_id`, `pose_state`.`state_id` `pivot_state_id`, `pose_state`.`status_id` `pivot_status_id`, `pose_state`.`created_at` `pivot_created_at`, `pose_state`.`updated_at` `pivot_updated_at` `states` inner join `pose_state` on `states`.`id` = `pose_state`.`state_id` `pose_state`.`pose_id` null , `pose_state`.`status_id` = ?
edit
when updated code removing scope worked. @deefour putting me on right path! maybe scope has else missing.
public function pendingreviews() { return $this->states() ->wherepivot('status_id','=', 10); }
yet edit
i got work. solution above giving me duplicate entries. no idea why works, does, stick it.
public function scopewithstatuscode($query, $tag) { $query->with(['states' => function($q) use ($tag) { $q->wherepivot('status_id','=', $tag); }]) ->wherehas('states',function($q) use ($tag) { $q->where('status_id', $tag); }); }
i think implementation of scopewithpendingreviews()
abuse of intended use of scopes.
that aside, believe you're not using wherepivot()
properly. according the source, method signature
public function wherepivot($column, $operator = null, $value = null, $boolean = 'and')
but you're treating as
public function wherepivot($column, $value = null, $boolean = 'and')
this means
->wherepivot('status_id',10)
should be
->wherepivot('status_id', '=', 10)
responding comments
a scope should thought of reusable set of conditions append existing query, if query
somemodel::newquery()
the idea pre-existing query further refined (read: 'scoped') conditions within scope method, not generate new query, , not generate new query based on associated model.
by default, first , argument passed scope method query builder instance itself.
your scope implementation on pose
model query against states
table did this
$this->states()
this why sql appears does. it's clear indicator you're misusing scopes. scope might instead this
public function scopewithpendingreviews($query) { $query->join('pose_state', 'poses.id', '=', 'pose_state.pose.id') ->where('status_id', 10); }
unlike new pendingreviews()
method returning query based on state
model, scope refine query on pose
model.
now can use scope intended.
$poses = pose::withpendingreviews();
which translated more verbose
$poses = pose::newquery()->withpendingreviews();
notice scope above doesn't return value. it's accepting existing query builder object , adding onto it.
the other answer question filled misinformation.
- you cannot use
wherepivot()
claims. - your use of
withtimestamps()
not @ related problem - you don't have "custom work" timestamps working. adding
withtimestamps()
call did needed. make sure havecreated_at
,updated_at
column in join table.