eloquent

์—˜๋กœํ€€ํŠธ

๋ผ๋ผ๋ฒจ์ด ์ œ๊ณตํ•˜๋Š” ORM๊ตฌํ˜„์ฒด๋กœ DB์™€ ๊ฐ์ฒด๊ฐ„ ๋งตํ•‘๊ธฐ์ˆ 

์ฟผ๋ฆฌ

>>> $post = App\Models\Post::get();

๋ชจ๋ธ ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•ด์„œ ์ฟผ๋ฆฌ๋นŒ๋”์™€ ๊ฐ™์ด ๋ฉ”์„œ๋“œ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๋Š” Modelํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

save()

>>> $post = App\Models\Post::first();
>>> $post->title = 'foo';
>>> $post->save();  //error๋ฐœ์ƒ

์œ„์—์„œ save()๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ, ์—˜๋กœํ€€ํŠธ๋Š” ๋ชจ๋“  ํ…Œ์ด๋ธ”์— created_at,updated_at์ด ์žˆ๋‹ค๊ณ  ๊ณผ์ •ํ•˜๊ณ  ํ˜„์žฌ์˜ ํƒ€์ž„์Šคํƒฌํ”„๊ฐ’์„ ํ• ๋‹นํ•˜๋Š”๋ฐ ํ•ด๋‹น ์ปฌ๋Ÿผ์ด ์กด์žฌํ•˜์ง€ ์•Š์•„ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ์ด๋‹ค. ํ•ด๋‹น ์ปฌ๋Ÿผ์„ ์ถ”๊ฐ€ํ•ด์ฃผ๊ฑฐ๋‚˜ ํƒ€์ž„์Šคํƒฌํ”„ ์ž๋™์ž…๋ ฅ๊ธฐ๋Šฅ์„ ๋„๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

public $timestamps = false;์„ ์ถ”๊ฐ€ํ•ด ์ž๋™์ž…๋ ฅ๊ธฐ๋Šฅ์„ ๋Œ ์ˆ˜ ์žˆ๋‹ค.

create()

save()๋ฉ”์„œ๋“œ๋Š” ๋ชจ๋ธ์˜ ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ํ•˜๋‚˜์”ฉ ํ• ๋‹นํ•ด์ฃผ์–ด์•ผ ํ•˜๋Š”๋ฐ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ”„๋กœํผํ‹ฐ๊ฐ’์„ ํ•œ๋ฒˆ์— ํ• ๋‹นํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” create()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŽธํ•˜๊ฒŒ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋‹ค.

>>> App\Models\Post::create([
    'email' => 'test@test.com',
    'password' => 'bcrypt('1234')',
]);

create()๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ associate array๋ฅผ ๋„˜๊ฒจ์ฃผ์–ด ๊ฐ’์„ ํ• ๋‹นํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.

bcrypt()๋Š” 60๋ฐ”์ดํŠธ์งœ๋ฆฌ ๋‹จ๋ฐฉํ–ฅ ํ•ด์‹œ๋ฅผ ๋งŒ๋“œ๋Š” ๋„์šฐ๋ฏธ ํ•จ์ˆ˜๋กœ ๋ณตํ˜ธํ™”๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ๋•Œ๋ฌธ์— ๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰์‹œ์ผœ๋ณด๋ฉด MassAssignmentException์ด ๋ฐœ์ƒํ•˜๋Š”๋ฐ ์ด๋Š” ์—˜๋กœํ€€ํŠธ ์ž์ฒด์—์„œ ํ•ด์ปค์˜ ๋Œ€๋Ÿ‰ ํ• ๋‹น ๊ณต๊ฒฉ์„ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•œ ์˜ˆ์™ธ์ด๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๋Š”๋ฐ ํ•˜๋‚˜๋Š” $fillable ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•˜๋Š” ํ—ˆ์šฉ๋ชฉ๋ก ๋ฐฉ์‹์ด๊ณ , ํ•˜๋‚˜๋Š” $guardedํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•œ ๊ธˆ์ง€๋ชฉ๋ก ๋ฐฉ์‹์ด๋‹ค.

์—ฐ๊ด€๊ด€๊ณ„

1. ์ผ๋Œ€๋‹ค ๊ด€๊ณ„

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned()->index();
            $table->timestamps();

            $table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
        });
    }

    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์—์„œ ๋‹ค(N)๊ฐ€ ๋˜๋Š” ์ชฝ์— foreign()๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ํ…Œ์ด๋ธ”๋ผ๋ฆฌ์˜ ์™ธ๋ž˜ ํ‚ค ๊ด€๊ณ„๋ฅผ ์—ฐ๊ฒฐ ํ•ด์ฃผ๊ณ  ๋ชจ๋ธ์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์—ฐ๊ฒฐ๊ด€๊ณ„๋ฅผ ํ‘œํ˜„ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

//User
class User extends Authenticatable
{
    use HasFactory, Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    public function posts(){
        return $this->hasMany(Post::class);
    }
}

//Post
class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'body',
    ];

    public $timestamps = false;

    public function user(){
        return $this->belongsTo(User::class,'custom_user_id');
    }
}

๊ฐ ๋ชจ๋ธ๋‚ด์—์„œ ์—ฐ๊ด€๊ด€๊ณ„์„ค์ •ํ•  ๋ชจ๋ธ์ด๋ฆ„์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด hasMany(), belongsTo()๋ฉ”์„œ๋“œ์™€ ๊ฐ™์ด ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ •์˜ ํ•ด์ค„ ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๋•Œ ๋ฉ”์„œ๋“œ ๋ช…์œผ๋กœ ๊ด€๋ก€์ƒ 1์ด ๋˜๋Š” ์ชฝ ๋ชจ๋ธ์„ ์ ‘๊ทผํ•˜๋Š” ๋ฉ”์„œ๋“œ๋Š” ๋‹จ์ˆ˜, N์ด ๋˜๋Š” ๋ชจ๋ธ์„ ์ ‘๊ทผํ•˜๋Š” ๋ฉ”์„œ๋“œ๋Š” ๋ณต์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. 1์ด๋˜๋Š”์ชฝ์—์„œ N์„ ์—ฐ๊ฒฐํ• ๋•Œ hasMany()๋ฅผ, N์ด ๋˜๋Š”์ชฝ์—์„œ 1์„ ์—ฐ๊ฒฐํ• ๋•Œ belongsTo()๋ฅผ ์ด์šฉํ•œ๋‹ค.

์™ธ๋ž˜ํ‚ค ์ด๋ฆ„์€ ๋ชจ๋ธ๋ช…์„ ๊ฐ€์ง€๊ณ  ์—˜๋ฆฌํ€€ํŠธ๊ฐ€ ์œ ์ถ”ํ•˜์—ฌ ์—ฐ๊ฒฐํ•˜์ง€๋งŒ ํŠน๋ณ„ํ•œ id๋กœ ์—ฐ๊ฒฐ์„ ์›ํ•œ๋‹ค๋ฉด Post๋ชจ๋ธ์˜ user()๊ณผ ๊ฐ™์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์™ธ๋ž˜ํ‚ค ์ด๋ฆ„์„ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค๋Œ€๋‹ค ์—ฐ๊ฒฐ

$ php artisan make:migration create_article_tag_table --create=article_tag

class CreateArticleTagTable extends Migration
{
    public function up()
    {
        Schema::create('article_tag', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('article_id')->unsigned();
            $table->integer('tag_id')->unsigned();

            $table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');
            $table->foreign('tag_id')->references('id')->on('articles')->onDelete('cascade');
        });
    }

    public function down()
    {
        Schema::dropIfExists('article_tag');
    }
}

N:N๊ด€๊ณ„๋ฅผ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ…Œ์ด๋ธ” ํ•œ๊ฐœ๋ฅผ ๋” ์ƒ์„ฑํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

//Post
class Post extends Model
{
    use HasFactory;

    public $timestamps = false;

    protected $fillable = [
        'title',
        'body',
    ];

    public function user(){
        return $this->belongsTo(User::class,'custom_user_id');
    }

    public function tags(){
        return $this->belongsToMany(Tag::class);
    }
}

//tag
class Tag extends Authenticatable
{
    use HasFactory, Notifiable;

    protected $fillable = [
        'name'
    ];

    public function posts(){
        return $this->belongsToMany(Post::class);
    }
}

N:N์€ ์–‘์ชฝ ๋‹ค belongsToMany()๋ฅผ ์ด์šฉํ•˜์—ฌ ์—ฐ๊ฒฐ์„ ํ•ด์ฃผ๋ฉด ๋˜๋Š”๋ฐ ์ฒซ๋ฒˆ์งธ์—์„œ ํ…Œ์ด๋ธ”์„ ํ•œ๊ฐœ๋” ์ƒ์„ฑํ•˜๋Š” ์ด์œ ๋Š” ์ด ํ…Œ์ด๋ธ”์ด N:N๊ด€๊ณ„๋ฅผ ์—ฐ๊ฒฐ์‹œ์ผœ์ฃผ๋Š” ํ”ผ๋ฒ— ํ…Œ์ด๋ธ”์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์กฐํšŒ

all()

$flights = App\Models\Flight::all();

foreach ($flights as $flight) {
    echo $flight->name;
}

all()๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํ…Œ์ด๋ธ”์„ ์กฐํšŒํ•  ์ˆ˜์žˆ์ง€๋งŒ ์ด๋Š” ๋ชจ๋“  ํ–‰์ด ์กฐํšŒ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฟผ๋ฆฌ๋นŒ๋”์™€ ๋น„์Šทํ•˜๊ฒŒ ์กฐ๊ฑด๋“ค์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

์—˜๋กœํ€€ํŠธ ๋ชจ๋ธ์€ ๋ชจ๋‘ ์ฟผ๋ฆฌ๋นŒ๋”์ด๊ธฐ ๋•Œ๋ฌธ์— ์ฟผ๋ฆฌ ๋นŒ๋”์˜ ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

$flights = App\Models\Flight::where('active', 1)
               ->orderBy('name', 'desc')
               ->take(10)
               ->get();

cursor()

$users = App\Models\User::cursor()->filter(function ($user) {
    return $user->id > 500;
});

foreach ($users as $user) {
    echo $user->id;
}

cursor๋ฉ”์„œ๋“œ๋Š” ๋‹จํ•˜๋‚˜์˜ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰์„ ํ†ตํ•ด ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ ์žˆ์–ด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ LazyCollection์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Collection ๋ฉ”์„œ๋“œ๋“ค์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์‚ฝ์ž…

$flight = new Flight;

$flight->name = $request->name;

$flight->save();

์ฟผ๋ฆฌ๋นŒ๋”์˜ insert๋ณด๋‹ค ๊ฐ„ํŽธํ•˜๊ฒŒ save()๋ฉ”์„œ๋“œ๋กœ ์‚ฝ์ž…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ ํƒ€์ž„์Šคํƒฌํ”„๋Š” ์ž๋™์œผ๋กœ ์„ค์ •๋˜์–ด ์ˆ˜๋™์œผ๋กœ ์ง€์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

๋˜ํ•œ, ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํ–‰์ด๋ผ๋ฉด update๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.

์†์„ฑ ๋ณ€๊ฒฝ ํ™•์ธ

isDirty() | isClean()

$user = User::create([
    'first_name' => 'Taylor',
    'last_name' => 'Otwell',
    'title' => 'Developer',
]);

$user->title = 'Painter';

$user->isDirty(); // true
$user->isDirty('title'); // true
$user->isDirty('first_name'); // false

$user->isClean(); // false
$user->isClean('title'); // false
$user->isClean('first_name'); // true

$user->save();

$user->isDirty(); // false
$user->isClean(); // true

ํ˜„์žฌ ๋ชจ๋ธ์ด db์— flush๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ๊ฐ ์ปฌ๋Ÿผ๋ณ„๋กœ ํ™•์ธ๊ธฐ ๊ฐ€๋Šฅํ•˜๋‹ค.

wasChanged()

$user = User::create([
    'first_name' => 'Taylor',
    'last_name' => 'Otwell',
    'title' => 'Developer',
]);

$user->title = 'Painter';
$user->save();

$user->wasChanged(); // true
$user->wasChanged('title'); // true
$user->wasChanged('first_name'); // false

ํ˜„์žฌ ์š”์ฒญ์ฃผ๊ธฐ๋‚ด์— ๋ชจ๋ธ์˜ ์†์„ฑ์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ

getOriginal()

$user = User::find(1);

$user->name; // John
$user->email; // john@example.com

$user->name = "Jack";
$user->name; // Jack

$user->getOriginal('name'); // John
$user->getOriginal(); // Array of original attributes...

flush๋˜๊ธฐ ์ „์˜ ๋ชจ๋ธ์˜ ์ˆ˜์ •๋œ ์ด์ „ ๊ฐ’์„ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ

๋Œ€๋Ÿ‰ ํ• ๋‹น

๋ชจ๋ธ์˜ ๊ฐ’ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ๊ฐ ์ฑ„์›Œ save()๋กœ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ• ์™ธ์— create()๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•œ๋ฒˆ์— ์ €์žฅ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

$flight = App\Models\Flight::create(['name' => 'Flight 10']);

ํ•˜์ง€๋งŒ, ์—˜๋กœํ€€ํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋Œ€๋Ÿ‰ ํ• ๋‹น์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์–ด fillable์†์„ฑ์— ์ปฌ๋Ÿผ๋“ค์„ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

Last updated