메뉴와 카테고리의 연관 관계 설정하기

php artisan make:migration create_category_menu_table --create="category_menu"

 

마이그레이션 파일 생성 후 up메서드에 내용을 아래와 같이 설정 해준다.

public function up()
{
    Schema::create('category_menu', function (Blueprint $table) {
        $table->foreignId('category_id')->constrained();
        $table->foreignId('menu_id')->constrained();
    });
}

 

카테고리 모델 설정

 

메뉴 모델 설정

 

menu에 카테고리 데이터 넘기기

 

menu의 view 단에서 카테고리를 잘 가져오는지 확인

 

현재 생성된 카테고리
카테고리 이름을 불러오는 모습

 

 

카테고리 데이터 삭제 시 

app > Http > Controller > Admin > MenuController.php

... 

public function destroy(Menu $menu)
{
    $menu->delete();
    $menu->categories()->detach(); // 중간 테이블 레코드 제거
    Storage::delete($menu->image);

    return to_route('admin.menus.index')->with('danger', 'Menu deleted successfully');
}

$menu->categories()->detach(); 를 사용해서 중간 테이블 레코드(메뉴id와 카테고리id를 관리)를 제거 할 수 있다.

 

 

그리고 Table과 Reservation 모델이 연관 관계인 경우

Table Model
Reservation Model

 

TableController

이렇게 Table컨트롤러에서 destroy가 실행될 때 연관 테이블인 reservations에서도 연결된 값을 삭제해 주기 쉽다.

$table->reservations()->delete();

 

유효성 검사 https://laravel.kr/docs/8.x/validation

 

라라벨 8.x - Validation-유효성검사

라라벨 한글 메뉴얼 8.x - Validation-유효성검사

laravel.kr

 

php artisan make:request CategoryStoreRequest

 

class CategoryStoreRequest extends FormRequest
{

    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => ['required'],
            'image' => ['required', 'image'],
            'description' => ['required'],
        ];
    }
    
    public function messages()
    {
        return [
            'name.required' => '닉네임은 필수 입니다.',
            'email.required' => '이메일은 필수 입니다.',
            'email.email' => '이메일 형식이 아닙니다.',
            'email.unique:users,email' => '이미 등록된 이메일이 있습니다.',
        ];
    }
}

authorize 메서드의 값을 true로 변경하고

rules 메서드에 조건을 설정 했다.

 

class Category extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'image', 'description'];
}

$fillable 변수에 값을 설정 한다.

 

컨트롤러에서의 store 메서드 설정

 

class CategoryController extends Controller
{
    
    ...
    
    public function store(CategoryStoreRequest $request)
    {
        $image = $request->file('image')->store('public/categories');

        Category::create([
            'name' => $request->name,
            'description' => $request->description,
            'image' => $image
        ]);

        return to_route('admin.categories.index');
    }

이미지는 storage > app > public > categories > 파일명으로 저장이 된다.

예) /storage/categories/6w0dsYRhYcWNrExEzJfAtZUYg74qgm4ova6USVy8.jpg

 

 

view에서 링크를 storage:link를 사용해서 설정 한다.

$ php artisan storage:link
<tbody>
    @foreach ($categories as $category)
        <tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
            <td scope="row" class="px-6 py-4 font-medium text-gray-900 dark:text-white whitespace-nowrap">
                {{ $category->name }}
            </td>
            <td scope="row" class="px-6 py-4 font-medium text-gray-900 dark:text-white whitespace-nowrap">
                <img src="{{ Storage::url($category->image) }}" alt="" class="w-16 h-16 rounded">
            </td>
            <td scope="row" class="px-6 py-4 font-medium text-gray-900 dark:text-white whitespace-nowrap">
                {{ $category->description }}
            </td>
        </tr>
    @endforeach
</tbody>

 

 

현재 Routes > web.php의 설정은 아래와 같다.

Route::middleware(['auth', 'admin'])->name('admin.')->prefix('admin')->group(function () {
    Route::get('/', [AdminController::class, 'index'])->name('index');
    Route::resource('/categories', CategoryController::class);
    Route::resource('/menus', MenuController::class);
    Route::resource('/tables', TableController::class);
    Route::resource('/reservations', ReservationController::class);
});

 

categories, menus, tables, reservations 의 경우 Route가 resource로 잡혀 있는데,

이경우 해당 카테고리에서 발생하는 주소는 클래스의 메소드명을 따라 간다.

 

아래 CategoryController를 보자

class CategoryController extends Controller
{

    public function index()
    {
        $categories = Category::all();
        return view('admin.categories.index', compact('categories'));
    }

    public function create()
    {
        return view('admin.categories.create');
    }
    
    ...

/categories 주소로 가면 CategoryController의 index 메서드가 연결이 되는데,

여기서 view는 resources > admin > categories > index.blade.php 파일로 연결을 한다.

 

index.blade.php 파일

파일에서 New Category 버튼의 링크경로를 보면 admin.categories.create로 route를 호출한다.

 

이 경우 web.php에서 CategoryController의 create 메서드로 따로 연결을 시키지 않아도 url 경로 메서드로 연결이 된다.

 

 

1. 컨트롤러 생성

php artisan make:controller Admin/MenuController -r
php artisan make:controller Admin/CategoryController -r
php artisan make:controller Admin/TableController -r
php artisan make:controller Admin/ReservationController -r

 

2. 라우팅 설정

라우팅 설정

Route::middleware(['auth', 'admin'])->name('admin.')->prefix('admin')->group(function () {
    Route::get('/', [AdminController::class, 'index'])->name('index');
    Route::resource('/categories', CategoryController::class);
    Route::resource('/menus', MenuController::class);
    Route::resource('/tables', TableController::class);
    Route::resource('/reservation', ReservationController::class);
});

 

 

3. 컨트롤러에서 view 파일 설정

class CategoryController extends Controller
{

    public function index()
    {
        return view('admin.categories.index');
    }

MenuController, CategoryController, TableController, ReservationController 에 각각 index메서드를

view로 연결 해준다.

 

 

4. blade 파일 생성

public function up()
{
    Schema::create('tables', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->integer('guest_number');
        $table->string('status')->default('avaliable');
        $table->string('location');
        $table->timestamps();
    });
}

php artisan make:model Category -m
php artisan make:model Menu -m
php artisan make:model Table -m
php artisan make:model Reservation -m
php artisan migrate

 

 

1. create_categories_table.php

public function up()
{
    Schema::create('categories', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->text('description');
        $table->string('image');
        $table->timestamps();
    });
}

 

2. create_menus_table.php

public function up()
{
    Schema::create('menus', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->text('description');
        $table->string('image');
        $table->decimal('price', 10, 2);
        $table->timestamps();
    });
}

 

3. create_tables_table.php

public function up()
{
    Schema::create('tables', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->integer('guest_number');
        $table->string('status')->default('avaliable');
        $table->string('location');
        $table->timestamps();
    });
}

 

4. create_reservations_table.php

public function up()
{
    Schema::create('reservations', function (Blueprint $table) {
        $table->id();
        $table->string('first_name');
        $table->string('last_name');
        $table->string('email');
        $table->string('tel_number');
        $table->dateTime('res_date');
        $table->unsignedBigInteger('table_id');
        $table->integer('guest_number');
        $table->timestamps();
    });
}

 

1. 로그아웃 버튼 추가

resources > views > layouts > navigation.blade.php

<!-- Authentication -->
<form method="POST" action="{{ route('logout') }}">
    @csrf

    <x-dropdown-link :href="route('logout')"
            onclick="event.preventDefault();
                        this.closest('form').submit();">
        {{ __('Log Out') }}
    </x-dropdown-link>
</form>

위 소스의 form 영역이 로그아웃 버튼이다.

해당 부분 소스를 복사해서 다른 곳에 넣으면 로그아웃 버튼이 나타난다.

 

 

2. 네비게이션 추가 링크

resources > views > layouts > navigation.blade.php

<!-- Navigation Links -->
<div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
    <x-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')">
        {{ __('Dashboard') }}
    </x-nav-link>
    @if (Auth::user()->is_admin)
        <x-nav-link :href="route('admin.index')" :active="request()->routeIs('admin.index')">
            {{ __('Admin') }}
        </x-nav-link>
    @endif
</div>

 

로그인 한 회원이 관리자일 경우 추가 버튼 링크 보이도록 설정

 

추가된 관리자 버튼

 

+ Recent posts