12週目ly MVC(part 2)


残りのテストケースに合格しましょう!!

1)コントローラの作成
テストボックスに行って、ファイルが存在する場所を教えてあげました.
このようにフォルダとファイルを作成しましょう.
  it('links controller 파일이 존재해야 합니다', () => {
    let hasLinksController = fs.existsSync('./controllers/links/index.js');
    expect(hasLinksController).to.be.true;
  });
controllers/links/index.js
getメソッドとpostメソッドは存在する必要があるので、まずメソッドを作成します.
メソッドの作成方法は、昨日解答したCmarket Databaseのコントローラ->indexです.jsを参照してください.
module.exports = {
  get: () => {},
  post: () => {}
}
2)ルータ接続
POST/links linksコントローラを実行するPOSTメソッド
GET/links linksコントローラを実行するgetメソッド
const express = require('express');
const router = express.Router();
const linksController = require('../controllers/links')

/* GET links listing. */
router.get('/', linksController.get);
router.get('/:id', linksController.redirect);
router.post('/', linksController.post);


module.exports = router;
先ほど作成したコントローラをリンクコントローラとして宣言し、接続すればいいです.
そして、応答すると、テストケースが通過します.
module.exports = {
  get: (req, res) => {
    res.end()
  },
  post: (req, res) => {
    res.end()
  }
}
3)コントローラ実施
次に、応答のみを提供するコントローラを実装します.
クラスはエンドポイントのAPIを教えています.作成を参照してください.
3-1) POST/links
postリクエストはreqです.bodyにURLリクエストを書く
要求されたurlが既存のデータベースに格納されているurlである場合、保存されたurlが返されます.
要求されたurlが存在しない場合(初期要求のurl)、そのurl情報がデータベースに格納され、201に戻る

findOrCreate
findOrCreateメソッドを使用してurlがない場合はurlがあるかどうかを確認します.
デフォルトでは、whereで見つからない場合に検索値を作成する値を作成します.const [url, created] = await model.url.findOrCreate({where:{}, defaults:{}})[url,created]は配列形式で返され、最初のパラメータが私がクエリーした、生成した成果物、createdがtrueであればfindOrCreateでurlを生成し、createdがfalseであれば、成果物がすでにあることを教えてくれたので、直接クエリーしました
Model Querying - Finders
const model = require('../../models')
// 모델을 사용해야 한다 
// models > index.js -> module.exports = db; db객체가 불러와진다

// models > index.js 파일은 모델을 생성하고 난 다음 파일시스템으로 읽어오는 역할을 한다 
// 모델이 하나가 아닐 수도 있으므로 url모델, class모델 등등 
// 이걸 직접 전부 읽어오는게 아니라 index.js에서 전부 읽어와서 모델안에 해당하는 필드 값으로 존재할 수있게 해준다
const {getUrlTitle, isValidUrl} = require('../../modules/utils')

module.exports = {
  post: (req, res) => {
    // req.body.url을 데이터베이스에 있는지 확인한다
    // 없을경우 새로 생성
    // 원본 url로 get 요청을 보내서 title태그 사이의 값을 얻어온다  --> modules/utils.js 에 정의되어 있다 
    // url 테이블의 title, url값을 저장한다 
    // 성공시에 방금 생성한 모델을 json 형태로 전송한다 
    const originUrl = req.body.url;
    if(!isValidUrl(originUrl)){
      return res.sendStatus(400);
    }
    getUrlTitle(originUrl, async (err, result)=>{
      if(err){
        return res.sendStatus(500);
      }
      const [url, created] = await model.url.findOrCreate({
        where: {
          url: originUrl,
        },defaults:{
          title: result, // getUrlTitle이 실행되면서 title을 얻어온 결과물을 넣어주면 된다
        }
      });
      if(created) {
        return res.status(201).json(url); // 생성
      }
      return res.status(201).json(url); // 조회
    });
  }
}
3-2) GET/links

Model Querying - Finders
const model = require('../../models')

const {getUrlTitle, isValidUrl} = require('../../modules/utils')

module.exports = {
  get: async (req, res) => {
    // url테이블의 전체 목록을 json으로 보내준다 
    const result = await model.url.findAll();
    if(!result){
      return res.sendStatus(204);
    }
    res.json(result);
  }
}
3-3) GET/links/:id
const model = require('../../models')
const {getUrlTitle, isValidUrl} = require('../../modules/utils')

module.exports = {
  redirect: async (req, res) => {
    const urlId = req.params.id;
    // urls 테이블에 urlId를 pk로 가진 레코드를 찾고 -> findByPk
    // 해당 레코드의 visits 필드의 값을 1 증가 -> update
    // 조회한 레코드의 url값으로 리디렉션 한다 
    const result = await model.url.findByPk(urlId); 
    await result.update({
      visits: result.visits + 1 
    })
    const redirectUrl = result.url;
    return res.redirect(redirectUrl)
  }
}
Model Querying - Finders
Model Querying - Basics
express redirect