app > Http > Controllers > API > V1 > BoardController.php
<?php
namespace App\Http\Controllers\API\V1;
use App\Http\Requests\Board\PostRequest;
use App\Models\Board;
use Illuminate\Http\Request;
class BoardController extends BaseController
{
protected $board = '';
...
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$boards = $this->board->latest()->paginate(10);
return $this->sendResponse($boards, 'Post list');
}
...
}
resources> js > components > board > Board.vue
<template>... </template>
<script>
export default{
...
methods: {
getResults(page = 1) {
this.$Progress.start();
axios.get('api/board?page=' + page).then(({ data }) => (this.boards = data.data));
this.$Progress.finish();
},
loadPosts(){
// if(this.$gate.isAdmin()){
axios.get("api/board").then(({ data }) => (this.boards = data.data));
// }
},
...
},
mounted() {
},
created() {
this.$Progress.start();
this.loadPosts();
this.$Progress.finish();
},
}
</script>
npm run dev 실행 후 board 게시판에 들어가면 글 목록을 확인할 수 있다.
저번 포스팅에서 DB seeding은 나중에 한다고 했는데, 페이지네이션 기능을 확인하기 위해 여기서 진행할 것이다. 먼저 기본적인 시딩을 해본 뒤 모델 팩토리 기능을 사용해보겠다. 이 포스팅을 참고하였다.
- 시더 생성
$ php artisan make:seeder BoardsTableSeeder
database > seeders 디렉토리에 BoardsTableSeeder.php가 생성된다.
- BoardsTableSeeder 작성
<?php namespace Database\Seeders; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; class BoardsTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('boards')->insert([ 'title' => '제목', 'content' => '내용', 'author' => 'gahui', 'photo' => 'https://item.kakaocdn.net/do/55e782636469ccb12293095086c2e0806fb33a4b4cf43b6605fc7a1e262f0845', ]); } }
- 다음 명령어를 사용하여 seeding (seeder의 run 메소드 실행)$ php artisan db:seed --class=BoardsTableSeeder
문제는 이렇게 하면 데이터가 겨우 하나 들어간다. 라라벨의 모델 팩토리 기능을 사용하면 DB 테이블에 랜덤한 가짜 데이터를 반복적으로 채워넣을 수 있다. 이 포스팅을 참고하였다.
- 모델 팩토리 생성
$ php artisan make:factory BoardFactory --model=Board
databases > factories 디렉토리에 BoardFactory.php가 생성된다.
- BoardFactory 작성
<?php namespace Database\Factories; use App\Models\Board; use Illuminate\Database\Eloquent\Factories\Factory; class BoardFactory extends Factory { /** * The name of the factory's corresponding model. * * @var string */ protected $model = Board::class; /** * Define the model's default state. * * @return array */ public function definition() { return [ 'title' => $this->faker->realText(30), 'content' => $this->faker->realText(), 'author' => 'gahui', 'photo' => 'https://item.kakaocdn.net/do/55e782636469ccb12293095086c2e0806fb33a4b4cf43b6605fc7a1e262f0845', 'created_at' => now(), 'updated_at' => now(), ]; } }
- 팅커 콘솔에서 데이터 삽입
$ php artisan tinker //팅커 콘솔 사용 >> \App\Models\Board::factory()->count(11)->create(); //데이터 11개 삽입
11개의 데이터가 생성된 것을 확인할 수 있다. (전에 생성해둔 데이터는 모두 지운 상태에서 진행하였다.)
페이지 기능이 잘 작동하는 것 또한 확인 가능하다.
글 목록이 아닌 해당 글을 클릭했을 때 글 내용을 보여주는 기능이다.
app > Http > Controllers > API > V1 > BoardController.php
public function show($id)
{
$board = $this->board->findOrFail($id);
return $this->sendResponse($board, 'Post Details');
}
resources > js >routes.js
{ path: '/board/:postId', name: 'read', component: require('./components/board/Post.vue').default }, //글 상세페이지
resources> js > components > board > Board.vue
<template>
...
<tbody>
<tr v-for="post in boards.data" :key="post.id">
<td>{{post.id}}</td>
<router-link :to="{name: 'read', params: { postId: post.id }}">
<td>{{post.title}}</td>
</router-link>
<td>{{post.author}}</td>
<td>{{post.created_at}}</td>
...
</tr>
</tbody>
...
</template>
화면을 예쁘게 구성하지는 않았고, 그냥 받아온 데이터만 출력하게 했다.
🔫 트러블 슈팅 - axios.get이 html을 리턴하는 문제
사실 여기서 백에서 json 데이터가 제대로 안 오고 html 파일이 오길래 애 좀 먹었다..
진짜 간단한 기능인데 오래걸렸다는 게 좀 창피하지만ㅋㅋ나중에 또 이런 문제가 생길지 모르니 해결 방안을 적어본다. 내 경우에는 프론트에서 백으로 요청을 보내는 url이 잘못 됐었다.😑 콘솔에 찍어 확인해보니 loadPost() 메소드에서 url을"/api/board/" + this.$route.params.postId
로 지정했더니 요청이/api/board/{id}
가 아닌board/api/board/{id}
로 보내지고 있었다^^;; 사실 왜 저렇게 지정되는진 아직 알아내지 못했는데 일단 아래 코드와 같이 url을 수정해서 해결하였다. (나중에 알게되면 다시 추가하겠어요 ㅎㅎ..)
resources > js > components > board > Post.vue
<template>
<div>
<p>ss</p>
<p>{{post.id}}</p>
<p>{{post.title}}</p>
<p>{{post.author}}</p>
<p>{{post.created_at}}</p>
<p>{{post.content}}</p>
<p>{{post.file}}</p>
</div>
</template>
<script>
export default{
data(){
return{
post: {},
}
},
methods: {
loadPost(){
axios.get("http://localhost:8000/api/board/"+this.$route.params.postId)
.then((res)=>{
console.log(res);
this.post = res.data.data
})
.then((err)=>{
console.log(err);
});
}
},
mounted() {
},
created(){
this.loadPost();
},
}
</script>
- 각 글의 제목에 링크가 생성되었다.
- 글의 제목을 클릭하면 해당 글의 상세 페이지로 이동된다. 화면 구성을 예쁘게 안 해서 가독성은 별로지만 해당 글의 상세 내용을 확인할 수는 있다.