본문 바로가기

코딩/Today I Learn

12.21 공부

728x90

upload.pug     

   input(type="file", accept="video/*", required, id="video", name="video")

 

middleware

export const  avatarUpload = multer({ 
    dest:"uploads/avatars/",
    limits:{
        fileSize: 3000000, --> byte
}})
export const  videoUpload = multer({ 
    dest:"uploads/videos/" ,
    limits:{
        fileSize: 10000000,
}})

 

videoRouter

videoRouter
    .route("/upload")
    .all(protectorMiddleware)
    .get(getUpload)
    .post(videoUpload.single("video"), postUpload);

 

videoController

export const postUpload = async (req, res) => {
  const file = req.file; 또는   const {path:fileUrl} = req.file;이렇게 적어도됨 es6 req.file.path 이름을 fileUrl로 바꾸기 
  const { title, description, hashtags } = req.body;
  try {
    await Video.create({
      title,
      description,
      fileUrl: file.path,
      hashtags: Video.formatHashtags(hashtags),
    });

 

Video.js 모델 

const videoSchema = mongoose.Schema({
    title: { type: String, required: true, uppercase: true, trim: true, minLength: 5 },
    fileUrl:{ type:String, required: true },

 

pug

multer로 폼을 보내고싶으면 템플릿에 항상 적어줘야함 

    form(method ="POST", enctype="multipart/form-data" )

 

watch

   video(src="/" + video.fileUrl, controls)

 

 

//////////////////////////

USER와 VIDEO연결하기 

USER에는 여러개의 VIDEO 의 _id

VIDEO에는 소유자의(한 명) _id

 

 

Video 모델에 owner속성을 추가할 건데

 

type:ObjectId라고 하면 다른 String, Number처럼 노란색으로 나타나지 않음  (자바스크립트에서사용하는 타입의미)

owner:{type:mongoose.Schema.Types.ObjectId}로 작성 

owner:{type:mongoose.Schema.Types.ObjectId, required:ture , ref:"User"} //object id 참고할 모델 이름

 

 

그리고 videoController에  postupload 수정

const {

    user:{ _id }

} =req.session 

try{

  await Video.create{

    owner: _id 

 }

}

 

--> 비디오 생성하고 db 열어보면 "owner": ObjectId("61c1cf35abbe2db93ce5981b"),로 속성이 추가됨 

지금 이 상태는 쓰잘때기 없음 -->populate 사용

 

block content 
   video(src="/" + video.fileUrl, controls )
   div
      p=video.description
      small=video.createdAt
      small= video.owner 

      br
      small= loggedInUser._id
   if video.owner == loggedInUser._id  // 두개의 형식이 각각 String, ObjectId여서 버튼이 보이지않음(적용이 되지않음)
      a(href=`${video.id}/edit`) Edit video → 
      br
      a(href=`${video.id}/delete`) Delete video → 

 

그래서    if String(video.owner) == String(loggedInUser._id)처럼 string으로 감싸기

 

 

watch controller에서 console.log(video)

//

Video 모델이 오너의 아이디를 가지고있다.

{
  meta: { views: 0, rating: 0 },
  _id: new ObjectId("61c1cf51abbe2db93ce5981e"),
  title: 'BUNNY',
  fileUrl: 'uploads/videos/7b75cfd35cfe0503be7a671e973811bb',
  description: 'bunny',
  hashtags: [ '#bunny', '#bunny' ],
  owner: new ObjectId("61c1cf35abbe2db93ce5981b"),
  createdAt: 2021-12-21T12:57:53.135Z,
  __v: 0
}

 

export const watch = async (req, res) => {
  const { id } = req.params;
  const video = await Video.findById(id);
  const owner = await User.findById(video.owner);
  if (!video) {
    return res.status(404).render("404", { pageTitle: "Video not found" });
  }
  return res.render("watch", { pageTitle: video.title, video, owner });
}

 

pug

block content 
   video(src="/" + video.fileUrl, controls )
   div
      p=video.description
      small=video.createdAt
   div 
      small= Uploaded by #{owner.name} 
   if String(video.owner) == String(loggedInUser._id)
      a(href=`${video.id}/edit`) Edit video → 
      br
      a(href=`${video.id}/delete`) Delete video → 

 

postupload Controller에서  

req.session의 id를 Video모델에 포함시켜 비디오 생성을 함

 비디오에 영상소유자의 id를넣으면 좋은 점 1  소유자이름표시  2.소유자와 로그인된사용자 id비교해 표시하기

지금 db를 두번 요청하는 방식(Video, User))은 좀 안좋아보여서 popluate 속성을 이용해 다시 코딩해보겠음 

 

 

-> 더 간단하게 populate : 실제데이터로 채워주는 역할 

export const watch = async (req, res) => {
  const { id } = req.params;
const video = await Video.findById(id).populate("owner") //mongoose가 'video'찾고 그 안에서 "owner" 찾아서 실제 데이터로 넣어줌  model 만들 때 ref"User" User 모델 참고하라고 설정했음   const owner = await User.findById(video.owner);
  if (!video) {
    return res.status(404).render("404", { pageTitle: "Video not found" });
  }
  return res.render("watch", { pageTitle: video.title, video, owner });

populate전 console.log(video)


}

populate 적용 후 

 

   small Uploaded by
         a(href=`/users/${video.owner._id}`)  #{owner.name video.owner.name} //owner변수 따로 안보내도 됨 

   if String(video.owner._id) == String(loggedInUser._id) //이제 video의 ower가 단순 문자가아니고 object객체라서 video.owner._id붙혀줘야함 

 

export const watch = async (req, res) => {
  const { id } = req.params;
const video = await Video.findById(id).populate("owner")
  if (!video) {
    return res.status(404).render("404", { pageTitle: "Video not found" });
  }
  return res.render("watch", { pageTitle: video.title, video, owner });

 

 

user id 에 해당하는 영상들 찾아서 나타내기

export const see = async(req, res) => {
    const {id} = req.params;
    const user = await User.findById(id);
    if(!user){
        return res.status(404).render("404",{pageTitle: "User not found"});
    }
    const videos = await Video.find({owner: user._id}) // 여러개의영상이라 findById 아니고 find({})

                                                                     //user._id는 오브젝트 형식이라 
    console.log(videos); 하면 배열로 나타남 
    return res.render("users/profile", {
        pageTitle: `${user.name}의 Profile`,
        user,
        videos,
    })
}

 

profile pug

 

extends ../base
include ../mixins/video

block content
    each video in videos
        +video(video)
    else
        li Sorry noth

 

 


위에 코드를 더 간단하게 만들기

 

유저는 여러가지 비디오를 가질 수있으니 videos라는 배열 속성을 만듦

const userSchema = new mongoose.Schema({
    email: { type: String, required: true, unique: true },
    avatarUrl:String,
    socialOnly:{type:Boolean, default:false},
    username: { type: String, required: true, unique: true },
    password: { type: String, },
    name: { type: String, required: true },
    location: String,
    videos:[{type: mongoose.Schema.Types.ObjectId , ref:"Video"}],
}); //Video model을 참고하여 objectId로 

 

업로드 될 영상의 id를 USER 모델에서 저장해야함 

export const postUpload = async (req, res) => {
  const {
    user: {  _id },
  } = req.session;
  const {path:fileUrl} = req.file;
  const { title, description, hashtags } = req.body;
  try {
    const newVideo = await Video.create({
      title,
      description,
      fileUrl,
      owner: _id,
      hashtags: Video.formatHashtags(hashtags),
    });
    const user = await User.findById(_id);
    user.videos.push(newVideo._id);
    user.save();

 

 

see Controller 

    const user = await User.findById(id).populate("videos");

populate로 video의 id 배열이아닌 video의 object를 자체를 가져옴 console.log(user)로 확인가능 

 

profile pug

block content 
    each video in user.videos


첫번 째 버그  비디오 업로드할 때마다 save();가 되는데

UserSchema에  저장하기 전 pre save 할 때 마다 비밀번호를 hashing 하라고 되어있기 때문

이는 사용자가 로그인을 못하게 되기 때문에 수정해야함

 

User.js 

userSchema.pre("save", async function () {

    if(this.isModified("password")){  비밀번호가 변경 됐을 때만   //여기서 this는 User가르킴 
        this.password = await bcrypt.hash(this.password, 5);
    }
});

 

두번째 버그 

사용자일 때만 비디오 수정,삭제접근하기  getEdit, postEdit, deletevideo

export const postEdit = async (req, res) => {
  const{
    user:{_id},
  } = req.session;
  const { id } = req.params;
  const { title, description, hashtags } = req.body;
  const video = await Video.exist({ _id: id });
  if (!video) {
    return res.status(404).render("404", { pageTitle: "Video not found" })
  }
  if (String(video.owner) !== String(_id)){
    return res.status(403).redirect("/"); //Stirng을 붙이지 않으면 값이 같더라도 타입이달라서 내가 영상 주인이라도  보이지않고 redirect 된다 , 타입은 typeof로 확인가능 
  }
  await Video.findByIdAndUpdate(id, {
    title,
    description,
    hashtags: Video.formatHashtags(hashtags),
  })
  return res.redirect(`/videos/${id}`);
}

 

 

 

deleteVideo 함수에서 User db에 남아있는 videos도 삭제

export const deleteVideo = async (req, res) => {
const { id } = req.params;
const {
user: { _id },
} = req.session;
const video = await Video.findById(id);
const user = await User.findById(_id);
if(!video){
return res.status(404).render("404", { pageTitle: "Video not found." });
}
if (String(video.owner) !== String(_id)) {
return res.status(403).redirect("/");
}

await Video.findByIdAndDelete(id);
user.videos.splice(user.videos.indexOf(id),1);
user.save();
return res.redirect("/");
}

'코딩 > Today I Learn' 카테고리의 다른 글

12.23공부  (0) 2021.12.23
12.22공부 프론트엔드 시작  (0) 2021.12.22
12.16일 공부  (0) 2021.12.16
12.15 공부  (0) 2021.12.15
12.9 공부  (0) 2021.12.14