edit 메소드 구현

이제 프로젝트 편집을 구현할 순서이며 이 기능은 편집 화면을 보여주는 edit() 메소드와 화면에서 반영을 클릭했을 때 호출되어 DB에 변경 내역을 반영하는 update() 두 가지 메소드를 구현해야 하며 먼저 edit() 메소드를 구현해 보겠습니다.

public function edit($id)
{
    $proj = Project::findOrFail($id);

    return view('project.edit')->with('proj', $proj);
}
CODE

모델을 찾아서 뷰에 전달만 하면 되므로 메소드는 매우 간단합니다. 하지만 이번 기능은 서버의 자원을 생성/수정하는 HTTP 메소드인 POST/PUT/PATCH/DELETE 를 사용하므로 뷰를 구현하기 전에 먼저 알아야 할 두 가지 중요한 라라벨의 특징이 있습니다.

CSRF 토큰 생성

미들웨어 항목에서 잠시 설명한 CSRF(Cross-Site Request Forgery)는  견고한 웹 서비스를 구현을 위해 서버의 자원을 생성/수정하는 기능에서 꼭 처리해야 하는필수 기능이며 라라벨은 백엔드 단에서 VerifyCsrfToken 미들웨어를 통해 자동으로 처리해 주므로 프론트엔드 단에서는 csrf 토큰만 삽입해 주면 됩니다.

이를 위해서는 폼 안에 이름이 _token 인 히든 필드를 만들고 csrf_token() 로 토큰을 설정해 주면 됩니다.

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
CODE

더 간단하게는 csrf_field() 헬퍼 메소드를 사용하면 위 코드와 동일한 결과를 출력합니다.

{{ csrf_field() }}
CODE

메소드 스푸핑

artisan route:list 를 통해 라우팅을 다시 한 번 확인해 보면 수정 기능은 HTTP 의 PUT 메소드를 사용하여 서버에 요청해야 하지만 HTML Form 은 PATCH, PUT, DELETE 메소드를 지원하고 않고 오직 GET/POST 만 지원합니다.

기능HTTP MethodURI라우트Action
수정 화면 표시GETproject/{project}/editproject.editProjectController@edit
수정 반영PUT/PATCHproject/{project}project.updateProjectController@update
삭제DELETEproject/{project}project.destroyProjectController@destroy

라라벨은 이를 해결하기 위해 메소드 스푸핑(method spoofing) 기능을 제공하며 다음과 같이 폼에 name이 _method 인 히든 값을 만들고 value 에 HTTP Method 명을 적어주면 라라벨의 라우팅 처리 로직이 자동으로 해당 메소드와 연결해 줍니다.

<input type="hidden" name="_method" value="PUT">
CODE

또는 간단하게 method_field() 헬퍼 함수의 파라미터로 HTTP 메소드를 지정하여 호출해도 동일한 결과를 얻을 수 있습니다.

{!! method_field('PUT') !!}
CODE

 

update 메소드 구현

브라우저가 보내온 수정된 데이타를 받아서 DB에 반영하는 update() 메소드를 구현할 순서입니다.

public function update(Request $request, $id)
{
    $proj = Project::findOrFail($id);

    $proj->update([	//1
        'name' => $request->get('name'),
        'description' => $request->get('description'),
    ]);

    return redirect('/project')
        ->with('message', $proj->name . '프로젝트가 수정되었습니다.');	//2
}
CODE
  • 1 : 브라우저가 보내온 데이타를 $request->get() 메소드를 사용하여 추출한후에 update() 로 반영합니다. 브라우저가 보낸 값을 모두 사용하지 말고 이렇게 필요한 항목을 뽑아서 사용하는게 보안 측면에서는 더 유리합니다.
  • 2 : 성공하면 결과 메시지를 표시하기 위해 with() 메소드를 사용하여 세션에 담아서 /project 라우트에 전달합니다.

이제 컨트롤러 구현은 끝났고 뷰 작성을 할 순서입니다.

 

edit 뷰 구현

project.edit 뷰 파일을 생성하고 코드를 작성합니다.

@extends('layouts.app')

@section('title')
    프로젝트 수정
@endsection

@section('content')

    <div class="col-md-8">
        <form class="form-horizontal" role="form" method="POST" action="{{ route('project.update', $proj->id) }}">	//1
            {{ method_field('PUT') }}	//2
            {{ csrf_field() }}			//3

            <div class="form-group">
                <label for="Project name">프로젝트 명</label>
                <div>
                    <input type="text" class="form-control" name="name" value="{{ $proj->name }}">
                </div>
            </div>

            <div class="form-group">
                <label for="설명">설명</label>
                <div>
                    <textarea class="form-control" rows="5" name="description">{{ $proj->description }}</textarea>
                </div>
            </div>
            <div class="form-group">
                <label for="생성일">생성일</label>
                <div>
                    <input type="text" class="form-control" name="created_at" value="{{ $proj->created_at }}" readonly="true">
                </div>
            </div>

            <div class="form-group">
                <div>
                    <button type="submit" class="btn btn-primary">
                        수정
                    </button>
                </div>
            </div>
        </form>
    </div>
@endsection
CODE
  • 1 : FORM의 액션을 POST 로 지정하고 route('project.update', $proj->id) 로 처리할 서버의 라우팅 이름과 리소스 id 를 지정합니다.
  • 2 : 메소드 스푸핑을 사용하여 PUT 메소드를 지정합니다.
  • 3: CSRF 토큰을 삽입합니다.

이제 뷰 작성이 완료되었고 브라우저를 열어서 수정 화면으로 들어가 봅시다.

데이타를 변경하고 수정 버튼을 클릭하여 서버에 반영하여 정상 동작하는지 확인해 봅시다.