일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
Tags
- observers
- AWS
- ndarray
- validate
- app:bind
- ORM
- 파이썬머신러닝완벽가이드
- app::singleton
- php
- rules
- ncloud
- relationships
- laravel7
- EloquentORM
- 머신러닝
- artisan:make service
- enV
- laravel
- laravel8
- cloudwatch
Archives
- Today
- Total
박유성의 라라벨 블로그
Eloquent ORM - Relationships (1부) 본문
Eloquent의 Relationship 처리는 심플한 코드와 더불어 여러 타입의 관계를 지원한다. Relationship 조작 시 생략 가능한 Primary Key 혹은 Foreign Key명으로 테이블이 만들어져 있다면 사용이 훨씬 간편해질 것이다.
하지만 대부분의 테이블들은 내 마음처럼 만들어져 있지 않다.
이처럼 내 맘 같지 않은 테이블들의 정보를 가지고 Eloquent의 Relationship의 각각의 타입별로 옵션 인자들을 예제와 함께 공부해 보는 시간을 가지려고 한다.
테스트 환경
-
PHP 7.3
-
Laravel 8.0
- Git Repository : github.com/meteorpark/laravel-relationship/
시나리오
총 3개의 테이블을 생성하여 다양한 형태의 relatoinship을 표현해 줄 것이다.
-
Users ( 회원 )
-
Cars ( 자동차 )
-
CarUser ( 회원이 보유한 자동차 )
마이그레이션 파일 생성
총 3개의 테이블을 생성해 보자
$ php artisan make:migration create_users_table
$ php artisan make:migration create_cars_table
$ php artisan make:migration create_car_user_table
모든 테이블의 컬럼명들은 사용하면 욕먹을 것 같은 이름들로 지어준다.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Class CreateUsersTable
*/
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create(
'users',
function (Blueprint $table) {
$table->id('user_id');
$table->string('name');
$table->timestamps();
}
);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Class CreateCarsTable
*/
class CreateCarsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create(
'cars',
function (Blueprint $table) {
$table->id('card_id');
$table->string('car_name');
$table->integer('price');
$table->timestamp('release_date')->nullable();
$table->timestamps();
}
);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('cars');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Class CreateCarUserTable
*/
class CreateCarUserTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create(
'car_user',
function (Blueprint $table) {
$table->id('user_car_id');
$table->bigInteger('user_pk_id');
$table->bigInteger('car_pk_id');
$table->string('note');
$table->timestamps();
}
);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('car_user');
}
}
마이그레이션 실행
$ php artisan migrate
Model 생성
$ php artisan make:model User
$ php artisan make:model Car
$ php artisan make:model UserCar
// app/Models/Car.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* Class Car
* @package App\Models
*/
class Car extends Model
{
use HasFactory;
/**
* @var string
*/
protected $primaryKey = 'car_id';
/**
* @var string[]
*/
protected $guarded = ['car_id'];
}
// app/Models/User.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* Class User
* @package App\Models
*/
class User extends Model
{
use HasFactory;
/**
* @var string
*/
protected $primaryKey = 'user_id';
/**
* @var string[]
*/
protected $guarded = ['user_id'];
}
// app/Models/CarUser.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* Class CarUser
* @package App\Models
*/
class CarUser extends Model
{
use HasFactory;
/**
* @var string
*/
protected $table = 'car_user';
/**
* @var string[]
*/
protected $guarded = ['car_user_id'];
}
테스트 데이터 생성
seeder 생성
$ php artisan make:seeder UserSeeder
$ php artisan make:seeder CarSeeder
$ php artisan make:seeder CarUserSeeder
// database/seeders/UserSeeder.php
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
/**
* Class UserSeeder
* @package Database\Seeders
*/
class UserSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
User::factory()->count(5)->create();
}
}
// database/seeders/CarSeeder.php
<?php
namespace Database\Seeders;
use App\Models\Car;
use Illuminate\Database\Seeder;
/**
* Class CarSeeder
* @package Database\Seeders
*/
class CarSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Car::factory()->count(5)->create();
}
}
pivot테이블의 데이터는 아래와 같이 가져온다. ( 더 좋은 방법이 있다면 코멘트 부탁드립니다 )
// database/seeders/CarUserSeeder.php
<?php
namespace Database\Seeders;
use App\Models\Car;
use App\Models\CarUser;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
/**
* Class CarUserSeeder
* @package Database\Seeders
*/
class CarUserSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
foreach (range(1, 30) as $index) {
$user = User::find(rand(1, 5));
$car = Car::find(rand(1, 5));
CarUser::create(
[
'user_pk_id' => $user->user_id,
'car_pk_id' => $car->car_id,
'note' => Str::random(15),
]
);
}
}
}
// database/seeders/DatabaseSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
/**
* Class DatabaseSeeder
* @package Database\Seeders
*/
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(
[
UserSeeder::class,
CarSeeder::class,
CarUserSeeder::class,
]
);
}
}
Factory 생성
// 자동자 faker data
$ composer require pelmered/fake-car
$ php artisan make:factory UserFactory
$ php artisan make:factory CarFactory
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
/**
* Class UserFactory
* @package Database\Factories
*/
class UserFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = User::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->name,
];
}
}
<?php
namespace Database\Factories;
use App\Models\Car;
use Illuminate\Database\Eloquent\Factories\Factory;
use Faker\Generator as Faker;
/**
* Class CarFactory
* @package Database\Factories
*/
class CarFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Car::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
$faker = (new \Faker\Factory())::create();
$faker->addProvider(new \Faker\Provider\Fakecar($faker));
return [
'car_name' => $faker->vehicleBrand.' '.$faker->vehicleModel,
'price' => $faker->numberBetween(30000000, 500000000),
'release_date' => $faker->dateTime,
];
}
}
$ php artisan db:seed
seed를 통해 데이터가 삽입된 것을 확인할 수 있다.
2부에서는 생성된 데이터를 활용하여 본격적으로 relationship에 대해 실습해 보겠다.
- 1부 끝
Comments