비중첩 Task 컨트롤러
작성한 중첩 태스크 컨트롤러는 프로젝트별로 접근해야 하므로 바로 태스크에 접근할 수 가 없으므로 우선 순위가 '높음'인 태스크나 완료 기한이 10일 이내인 태스크를 뽑는등의 경우 중첩 컨트롤러로는 불편하므로 /task 로 접근할 수 있는 태스크 컨트롤러가 필요합니다.
그러면 먼저 Task 컨트롤러를 artisan 명령어로 생성합니다.
$ artisan make:controller TaskController --resource
CODE
Partial Resource route
새로운 태스크 콘트롤러는 특정 조건에 맞는 전체 태스크를 조회하려는 용도이므로 모든 리소스 컨트롤러의 메소드가 필요하지 않습니다. 라라벨은 이를 위해 필요한 일부 메소드만 라우팅에 등록할 수 있는 기능을 제공하며 아래와같이 only 키워드로 사용할 메소드만 지정해주면 됩니다.
Route::group(['middleware' => 'auth'], function () {
Route::resource('project', 'ProjectController');
Route::resource('project.task', 'ProjectTaskController');
Route::resource('task', 'TaskController', ['only' => [ // 1
'index', 'show',
]]);
});
CODE
except 키워드도 사용할 수 있으며 이경우 제외할 메소드를 기술하며 다음은 create(), store(), destroy() 를 제공하지 않는 partial resource route 입니다.
Route::resource('task', 'TaskController', ['except' => [
'create', 'store', 'destroy',
]]);
CODE
이제 생성된 TaskController 를 열어서 index() 메소드를 구현합니다.
public function index()
{
$user = \Auth::user();
$start_date = \Carbon\Carbon::now(); // 1
$end_date = $start_date->copy()->addMonths(1); // 2
$tasks = $user->tasks() // 3
->orderBy('due_date', 'desc') // 4
->get();
return view('task.index') // 5
->with('tasks', $tasks)
->with('start_date', $start_date)
->with('end_date', $end_date);
}
CODE
- 1 : 카본 라이브러리로 현재 시간을 구합니다.
- 2: 기본 검색 조건은 오늘부터 만료일이 한달 이내인 태스크로 설정하기 위해 한 달을 더한 카본 객체를 만듭니다. 카본의 날자 함수는 현재 인스턴스를 수정하므로 $start_date->copy() 메소드로 인스턴스를 복제한 후에 사용해야 합니다.
- 3: 현재 로그인 한 사용자의 모든 태스크를 가져오기 위해 hasManyThrough() 관계로 설정한 tasks() 메소드를 호출합니다.
- 4: 완료 날자별로 내림차순으로 정렬하기 위해 orderBy( string $column, string $direction = 'asc') 를 사용합니다.
- 5: 검색한 결과를 뷰에 전달합니다.
이제 뷰를 만들 순서로 resources/views/task/index.blade.php 파일을 만들고 다음 내용을 추가합니다.
<form class="form-horizontal" role="form" method="GET" action="{{ route('task.index')}}"> //1
<div class="container">
<div class='col-md-3'>
<div class="form-group">
<label for="시작일">검색 시작일</label>
<div class='input-group date' id='start_date'>
<input type='text' class="form-control" name="start_date"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<div class='col-md-3'>
<div class="form-group">
<label for="종료일">검색 종료일</label>
<div class='input-group date' id='end_date'>
<input type='text' class="form-control" name="end_date"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<div class='col-md-2'>
<div class="form-group">
<label for="순위">우선순위</label>
<select class="form-control" name="priority">
@foreach(['all', '낮음', '보통', '높음'] as $p) //2
<option value="{{$p}}">{{$p}}</option>
@endforeach
</select>
</div>
</div>
<div class='col-md-2'>
<div class="form-group">
<label for="상태">상태</label>
<select class="form-control" name="status">
@foreach(['all','등록', '진행', '완료'] as $s) //3
<option value="{{$s}}">{{$s}}</option>
@endforeach
</select>
</div>
</div>
<div class='col-md-2'>
<div class="form-group">
<div>
<button type="submit" class="btn btn-primary">
찾기
</button>
</div>
</div>
</div>
</div>
</form>
<script type="text/javascript">
$(function () {
$('#start_date').datetimepicker({
defaultDate: '{{ $start_date }}',
format: 'YYYY-MM-DD HH:mm:ss'
});
$('#end_date').datetimepicker({
defaultDate: '{{ $end_date }}',
format: 'YYYY-MM-DD HH:mm:ss',
useCurrent: false //Important! See issue #1075
});
$("#start_date").on("dp.change", function (e) {
$('#end_date').data("DateTimePicker").minDate(e.date);
});
$("#end_date").on("dp.change", function (e) {
$('#start_date').data("DateTimePicker").maxDate(e.date);
});
});
</script>
<h3>태스크 목록</h3>
<table class="table table-striped">
<thead>
<tr>
<td>프로젝트</td>
<td>태스크</td>
<td>우선순위</td>
<td>상태</td>
<td>기한</td>
</tr>
</thead>
<tbody>
@foreach ($tasks as $task)
<tr>
<td>
{{ $task->project->name }}
</td>
<td>
<a href="{{route('project.task.show', [$task->project->id, $task->id])}}">{{ $task->name }}</a>
</td>
<td>
{{ $task->priority }}
</td>
<td>
{{ $task->status }}
</td>
<td>
{{ $task->due_date }}
</td>
<td>
<a class="btn btn-success" href="{{ route('project.task.edit', [$task->project->id, $task->id]) }}">편집</a>
</td>
<td>
<form method="POST" action="{{ route('project.task.destroy', [$task->project->id, $task->id]) }}">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" class="btn btn-danger">
삭제
</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
CODE
- 1: 상단에 검색 조건을 위한 달력 컨트롤과 콤보 박스를 추가합니다.
- 2, 3: 옵션 리스트를 출력하기 위해 foreach로 루프를 돕니다.
태스크 목록