Сейчас я группирую записи времени по категориям и месяцам. Категории хранятся в отдельной таблице, и я ссылаюсь на них в таблице основного времени с ограничением внешнего ключа category_id. Я группирую время по category_id, но вместо этого я хочу сгруппировать их по названию категории, поэтому строковое значение.
Должен ли я просто сохранить категории в моей основной таблице времени, создавая столбец для категорий?
В настоящее время у меня есть таблица 'times' с:
Schema::create('times', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('category_id');
$table->date('start_day');
$table->time('start_time');
$table->time('finish_time');
$table->time('duration');
$table->text('notes');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('category_id')->references('id')->on('categories');
}
и таблица категорий с:
Schema::create('categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
$table->string('type');
});
}
Я группирую время по категориям и месяцам, как показано ниже:
public function show(User $user)
{
$data = collect(array_fill(1, 12, []))
->replace(
$user->times()
->whereYear('start_day', 2019)
->groupBy('category_id', \DB::raw('month(start_day)'))
->select([
'category_id',
\DB::raw('month(start_day) as month'),
\DB::raw('sum(duration) as duration'),
])
->orderBy(\DB::raw('month(start_day)'))
->get()
->mapToGroups(function ($item) {
return [$item['month'] => [
$item['category_id'] => $this->formatDuration($item['duration'])
]];
})
->mapWithKeys(function ($item, $key) {
return [$key => $item->collapse()];
})
)
->mapToGroups(function ($item, $key) {
$month = \DateTime::createFromFormat('!m', $key)->format('M');
return [$month => $item];
});
return view('report.show', compact('data'));
}
Если я dd ($ data), это выводится с примером одноразовой записи для каждой категории на ноябрь,Всего у меня есть 5 категорий:
Collection {#327 ▼
#items: array:12 [▼
"Jan" => Collection {#315 ▶}
"Feb" => Collection {#332 ▶}
"Mar" => Collection {#335 ▶}
"Apr" => Collection {#334 ▶}
"May" => Collection {#333 ▶}
"Jun" => Collection {#316 ▶}
"Jul" => Collection {#320 ▶}
"Aug" => Collection {#313 ▶}
"Sep" => Collection {#318 ▶}
"Oct" => Collection {#294 ▶}
"Nov" => Collection {#321 ▼
#items: array:1 [▼
0 => Collection {#336 ▼
#items: array:5 [▼
0 => "12:00"
1 => "11:00"
2 => "12:00"
3 => "12:00"
4 => "12:00"
]
}
]
}
"Dec" => Collection {#328 ▶}
]
Вместо того, что я хочу, чтобы вывод был:
"Nov" => Collection {#321 ▼
#items: array:1 [▼
0 => Collection {#336 ▼
#items: array:5 [▼
'Category Type 1' => "12:00"
'Category Type 2' => "11:00"
'Category Type 3' => "12:00"
'Category Type 4' => "12:00"
'Category Type 5' => "12:00"
]
}
Есть ли способ ссылки на «тип» из таблицы категорий,с помощью category_id?
Модель времени:
class Time extends Model
{
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
public function category()
{
return $this->hasOne('App\Category');
}
}
Модель категории:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class Category extends Model
{
protected $guarded = [];
public function time() {
return $this->belongsTo('App\Time');
}
}
Модель пользователя:
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
public function times()
{
return $this->hasMany(Time::class);
}
public function categories()
{
return $this->hasMany('App\Category');
}
}