База даних
Concept Core використовує Illuminate Database (Capsule + Eloquent) —
той самий шар, що й у Laravel Eloquent.
Підключення, моделі, міграції та сидери інтегровані через DatabaseServiceProvider ядра.
HTTP і CLI працюють з однією конфігурацією (config/db.php, .env);
схему оновлюють консольними командами db:* (див. Консоль).
Шляхи міграцій і сидерів компонентів підключає ComponentsServiceProvider
(див. Створення компонента).
Класи ядра
| Клас | Роль |
|---|---|
DatabaseServiceProvider |
Capsule, Eloquent, Migrator, реєстри міграцій/сидерів |
DatabaseInterface |
Обгортка capsule() для query builder поза моделлю |
MigrationRegistry |
Шляхи до каталогів міграцій (додаток + компоненти) |
SeederRegistry / SeederManager |
Список сидерів і запуск через db:seed |
Підключення
Параметри з config/db.php перекриваються змінними оточення
(DB_HOST → db.host тощо). Детальна таблиця — у
Конфігурація → db.php та змінні оточення в тому ж розділі.
// config/db.php
return [
'db' => [
'driver' => 'mysql',
'host' => '127.0.0.1',
'port' => '3306',
'database' => 'concept_db',
'username' => 'root',
'password' => '',
'charset' => 'utf8mb4',
],
];
У DatabaseServiceProvider::boot() створюється глобальний
Illuminate\Database\Capsule\Manager, викликається bootEloquent(),
підключається Dispatcher для подій запитів.
SQL логується за log.db_queries (QueryLogger → storage/logs/query.log).
Телеметрію TelemetryEvent::DB_QUERY_EXECUTED записують окремо за
telemetry.enabled і telemetry.db_queries.
Низькорівневий доступ — Concept\Core\Services\Database\Contracts\DatabaseInterface
і метод capsule() (наприклад у правилах unique / exists).
Ключ db.port є в конфігу, але getConnectionOptions() ядра наразі
передає в Capsule лише driver, host, database,
username, password, charset.
Моделі Eloquent
Додаток наслідує Concept\App\Models\BaseModel (розширює
Illuminate\Database\Eloquent\Model). Компоненти оголошують моделі у власному namespace,
наприклад Concept\Components\AuthAdmin\Models\UserModel.
Рекомендовані практики:
- константи полів
FIELD_*замість «магічних» рядків у запитах іfillable; BaseModel::getId(),FIELD_ID,SORT_ASC/SORT_DESC;$fillable,$hidden,$casts,SoftDeletes— як у Laravel;- модель у конструктор контролера або сервісу — autowiring (
UserModel $userModel).
use Concept\App\Models\BaseModel;
use Illuminate\Database\Eloquent\SoftDeletes;
class UserModel extends BaseModel
{
use SoftDeletes;
public const string FIELD_EMAIL = 'email';
public const string FIELD_PASSWORD = 'password';
public const string FIELD_CREATED_AT = 'created_at';
protected $table = 'users';
protected $fillable = [self::FIELD_EMAIL, /* ... */];
protected $hidden = [self::FIELD_PASSWORD];
}
Запити в коді
Запити будуються через $model->newQuery() (query builder / Eloquent),
не через статичні виклики на класі моделі. Це узгоджено з ін’єкцією моделі в конструктор.
public function __construct(
private readonly UserModel $userModel,
private readonly ConfigInterface $config,
) {}
public function index(): ResponseInterface
{
$users = $this->userModel
->newQuery()
->orderBy(UserModel::FIELD_CREATED_AT, BaseModel::SORT_DESC)
->paginate($this->config->getInt('pagination.per_page', 10))
->withQueryString();
return $this->viewResponse->create('@auth-admin/users/list', ['users' => $users]);
}
Створення записів після валідації — newQuery()->create([...]) або
validated() з FormRequest (див. Запити та валідація).
Офіційні довідники: Eloquent,
Query Builder,
Pagination.
Міграції
Каталоги міграцій реєструються в config/migrations.php (додаток) і через
ComponentInterface::migrationPaths().
Під час ComponentsServiceProvider::boot() шляхи всіх увімкнених компонентів
додаються до MigrationRegistry.
// config/migrations.php
return [
'migrations' => [
'table' => 'migrations',
'paths' => ['database/migrations'],
],
];
// AuthAdminComponent::migrationPaths()
public function migrationPaths(): array
{
return [
$this->pathManager->toRelative($this->componentDir . '/Database/Migrations'),
];
}
Файл міграції — анонімний клас, що розширює Migration, з методами up() / down().
Приклад іменування файлів: V2026_03_23_120000_CreatePagesTable.php.
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Capsule\Manager as CapsuleManager;
return new class extends Migration
{
public function up(): void
{
CapsuleManager::schema()->create('pages', function (Blueprint $table) {
$table->increments('id');
$table->string('slug', 255)->unique();
$table->timestamps();
});
}
public function down(): void
{
CapsuleManager::schema()->dropIfExists('pages');
}
};
db:migrate створює таблицю migrations, якщо її ще немає, і застосовує
всі невиконані файли з усіх зареєстрованих шляхів.
Документація Laravel: Migrations.
Сидери
Класи сидерів перелічуються в config/seeders.php і в
ComponentInterface::seeders().
SeederManager викликає run() лише для класів, що реалізують
Concept\Core\Services\Database\Contracts\SeederInterface.
Зазвичай сидер також extends Illuminate\Database\Seeder.
// config/seeders.php
use Database\Seeders\PageSeeder;
return [
'seeders' => [
'list' => [PageSeeder::class],
],
];
// database/seeders/PageSeeder.php — обов'язково SeederInterface
use Concept\Core\Services\Database\Contracts\SeederInterface;
use Illuminate\Database\Seeder;
class PageSeeder extends Seeder implements SeederInterface
{
public function run(): void { /* ... */ }
}
db:seed без опцій запускає всі зареєстровані сидери.
Щоб виконати один сидер, передайте повний FQCN класу через
-c (або --class) — коротке ім’я класу не підтримується.
Значення бажано взяти в лапки через зворотні слеші в namespace:
php bin/console.php db:seed -c "Concept\Components\AuthAdmin\Database\Seeders\UserSeeder"
Список доступних класів: php bin/console.php seeders:list.
Консоль
| Команда | Призначення |
|---|---|
db:migrate | Застосувати нові міграції |
db:rollback | Відкат останнього batch |
migration:list | Список міграцій і статус |
db:seed | Усі сидери; -c "Fully\Qualified\Class" — один сидер (повний FQCN) |
seeders:list | Зареєстровані сидери |
php bin/console.php db:migrate
php bin/console.php db:seed
php bin/console.php db:seed -c "Database\Seeders\PageSeeder"
php bin/console.php db:seed -c "Concept\Components\AuthAdmin\Database\Seeders\UserSeeder"
Перед першим db:migrate переконайтесь, що БД створена і
DB_* у .env відповідають вашому середовищу.
Розташування файлів
config/db.php
config/migrations.php
config/seeders.php
database/migrations/ # міграції додатку
database/seeders/ # сидери додатку (namespace Database\Seeders)
src/App/Models/BaseModel.php
src/Components/*/Models/
src/Components/*/Database/Migrations/
src/Components/*/Database/Seeders/
API запитів, відношень, scope, soft deletes і cast enum — як у Laravel Eloquent; відмінності лише в bootstrap (Capsule замість повного Laravel) та реєстрації шляхів міграцій/сидерів через конфіг і компоненти.