who*_*boy 5 php laravel eloquent laravel-5
我正在与Laravel 5合作,我遇到了解决->wherePivot()多对多关系的问题.当我dd()使用SQL时,它看起来像Eloquent正在使用`pose_state`来查找数据透视表中的记录.`pose_id`为null`.
我希望这是一个简单的错误,而不是一个错误.任何想法都表示赞赏.
提出
id
name
type
Run Code Online (Sandbox Code Playgroud)
州
id
name
machine_name
Run Code Online (Sandbox Code Playgroud)
pose_state
pose_id
state_id
status
Run Code Online (Sandbox Code Playgroud)
提出
<?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);
}
}
Run Code Online (Sandbox Code Playgroud)
州
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class State extends Model {
public function poses()
{
return $this->belongsToMany('Pose')
->withPivot('status_id')
->withTimestamps();
}
}
Run Code Online (Sandbox Code Playgroud)
PosesController功能
public function listPosesForReview(){
$poses = Pose::withPendingReviews()->get();
dd($poses->toArray() );
}
Run Code Online (Sandbox Code Playgroud)
SQL
select
`states`.*, `pose_state`.`pose_id` as `pivot_pose_id`,
`pose_state`.`state_id` as `pivot_state_id`,
`pose_state`.`status_id` as `pivot_status_id`,
`pose_state`.`created_at` as `pivot_created_at`,
`pose_state`.`updated_at` as `pivot_updated_at`
from
`states` inner join `pose_state` on `states`.`id` = `pose_state`.`state_id`
where
`pose_state`.`pose_id` is null and `pose_state`.`status_id` = ?
Run Code Online (Sandbox Code Playgroud)
当我更新我的代码以删除其工作的范围.感谢@Deefour让我走上了正确的道路!也许范围还有其他我想念的东西.
public function pendingReviews()
{
return $this->states()
->wherePivot('status_id','=', 10);
}
Run Code Online (Sandbox Code Playgroud)
我终于开始工作了.上面的解决方案给了我重复的条目.不知道为什么会这样,但确实如此,所以我会坚持下去.
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);
});
}
Run Code Online (Sandbox Code Playgroud)
我认为您的实现scopeWithPendingReviews()是对范围的预期用途的滥用。
范围应被视为附加到现有查询的可重用条件集,即使该查询只是简单的
SomeModel::newQuery()
Run Code Online (Sandbox Code Playgroud)
这个想法是,预先存在的查询将通过范围方法内的条件进一步细化(读取:“范围”),而不是生成新查询,并且绝对不会基于关联模型生成新查询。
默认情况下,传递给范围方法的第一个也是唯一的参数是查询构建器实例本身。
一旦您执行此操作,您Pose模型上的作用域实现实际上就是对表的查询states
$this->states()
Run Code Online (Sandbox Code Playgroud)
这就是您的 SQL 出现的原因。这也清楚地表明您滥用了范围。范围可能看起来像这样
public function scopeWithPendingReviews($query) {
$query->join('pose_state', 'poses.id', '=', 'pose_state.pose.id')
->where('status_id', 10);
}
Run Code Online (Sandbox Code Playgroud)
pendingReviews()与基于模型返回查询的新方法不同State,此范围将优化模型上的查询Pose。
现在您可以按照最初的预期使用示波器。
$poses = Pose::withPendingReviews();
Run Code Online (Sandbox Code Playgroud)
这可以翻译成更详细的
$poses = Pose::newQuery()->withPendingReviews();
Run Code Online (Sandbox Code Playgroud)
另请注意,上面的范围不返回值。它接受现有的查询构建器对象并添加到其中。
这个问题的另一个答案充满了错误信息。
wherePivot()原样使用声明。withTimestamps()与您的问题完全无关withTimestamps()只需像您一样添加呼叫即可。只需确保连接表中有一个created_atand列即可。updated_at| 归档时间: |
|
| 查看次数: |
18780 次 |
| 最近记录: |