我有两个表,schedules
和shifts
,关系是一对多。
schedule
包含day
,month
,year
字段以及is_published
布尔值。 shift
user_id
与users
具有一对一的关系。
现在,我想获得shifts
的下一个即将到来的user
。我必须从schedule
开始,因为该表中包含日期。但是,更重要的是,我应该只检索属于已发布的shifts
的{{1}}。
所以最大的问题是:
参赛作品数量应为5班制。但是,从计划开始,我不知道需要检索多少计划,直到有5个属于用户的班次。
除了试验和错误(即检索x下一个时间表并进行测试以查看是否存在足够的班次。如果没有,检索下一个n个时间表直到满足配额),是否有替代方案?
附表架构
schedule
此处,Schema::create('schedules', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id', false, true);
$table->integer('client_id', false, true);
$table->datetime('for');
$table->enum('type', array('template', 'revision', 'common'));
$table->string('name', 50)->default('Untitled Template');
$table->boolean('is_published');
$table->timestamp('published_at');
$table->softDeletes();
$table->timestamps();
});
是创建者的ID,而不是时间表所属的身份。这用于跟踪未来如何创建计划。
转变架构
user_id
答案 0 :(得分:0)
SELECT user.name,inner_q。* FROM user, (SELECT sch.year,sch.month,sch.day,sh.start_time FROM schedule sch INNER JOIN shift sh ON sch.id = sh.schedule_id WHERE sch.is_published = TRUE AND sh.user_id = user.id LIMIT 5)AS inner_q;
答案 1 :(得分:0)
好的,我不知道我是否做得好,但试一试:
User::find($userId)
->shifts()
->with('schedule')
->where('is_published', true)
->orderBy('year', 'asc')
->orderBy('month', 'asc')
->orderBy('day', 'asc')
->take(5)
->get();
<强>更新强>
第二次尝试,希望这有效
User::find($userId)
->schedules()
->has('shifts')
->where('is_published', true)
->orderBy('year', 'asc')
->orderBy('month', 'asc')
->orderBy('day', 'asc')
->take(5)
->get();
另一次更新
第三次是魅力:)
$results = User::find($userId)
->schedules()
->where('is_published', true)
->orderBy('year', 'asc')
->orderBy('month', 'asc')
->orderBy('day', 'asc')
->take(5)
->get();
为此,您需要在用户模型中使用此功能:
public function schedules(){
return $this->belongsToMany('Schedule', 'shifts');
}
然后,要访问班次,您可以使用pivot属性:
foreach($results as $result){
echo $result->pivot
}
如果您想要完整的Shift模型而不仅仅是属性,请将其定义为Pivot Model:
class Shift extends Illuminate\Database\Eloquent\Relations\Pivot
并在Schedule模型中:
public function newPivot(Eloquent $parent, array $attributes, $table, $exists){
if ($parent instanceof User) {
return new Shift($parent, $attributes, $table, $exists);
}
return parent::newPivot($parent, $attributes, $table, $exists);
}
答案 2 :(得分:0)
我会采取简单的方法:
// User model
public function shifts()
{
return $this->hasManyThrough('Shift', 'Schedule');
}
然后:
$now = Carbon\Carbon::now();
$upcomingShifts = $user->shifts()
->where('schedules.is_published', 1)
->where('schedules.for', '>', $now)
->orderBy('schedules.for')
->take(5)
->get();
你可以让它更灵活,例如。这样:
// User model
public function getUpcomingShifts($limit = 5)
{
$joinTable = $this->shifts()->getParent()->getTable(); // schedules
$now = Carbon\Carbon::now();
return $this->shifts()
->where($joinTable.'.is_published', 1)
->where($joinTable.'.for', '>', $now)
->orderBy($joinTable.'.for')
->take($limit)
->get();
}
// then
$user->getUpcomingShifts();