인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

d\/b님의 프로필 이미지
d\/b

작성한 질문수

[리뉴얼] React로 NodeBird SNS 만들기

addHashtags

작성

·

506

0

안녕하세요. 

제 프로젝트에 맞게 조금 수정한 부분입니다. 강의에서 post 가 profile로 바꼈다고 생각하시면 됩니다.

Profile.associate = (db) => {
db.Profile.hasOne(db.Image)
db.Profile.hasMany(db.Contact) //profile.addContacts, profile.getContacts
db.Profile.belongsTo(db.User) // profile.addUser, profile.getUser, profile.setUser
db.Profile.belongsToMany(db.Hashtag , {through:"ProfileTag"}) //profile.addHashtags
db.Profile.belongsToMany(db.Profile,{through:"Like", as:"Liking",foreignKey:"LikerId"})
db.Profile.belongsToMany(db.Profile,{through:"Like", as:"Liker",foreignKey:"LikingId"})
};
Hashtag.associate = (db) => {
db.Hashtag.belongsToMany(db.Profile, {through:"ProfileTag"})
};

//router

router.post("/add", isLoggedIn, upload.none(), async (req, res, next) => {
try {
...

if (tag) {
const hashtags = tag.match(/#[^\s#]+/g);
const result = await Promise.all(
hashtags.
map((tag) =>
Hashtag.findOrCreate({ where: { name: tag.slice(1).toLowerCase() } })
)
)
;
await profile.addHashtags(result.map(p=>p[0])); // 이 부분에서 오류
}

프로필과 해시태그를 만들었고 데이터베이스에 각각 올라간 것까지 확인했습니다. 근데 addHashtags 에서 막히는 것 같습니다.

아래 오류 메세지를 확인했을 때 58번 프로필이 21,22,23 해시태그를 생성한 것까지 콘솔에 찍힙니다. 바로 그 다음 오류메세지가 나는데 어떻게 해결해야할지 모르겠습니다 ㅠ

Executing (default): INSERT INTO `ProfileTag` (`createdAt`,`updatedAt`,`ProfileId`,`HashtagId`) VALUES ('2021-07-18 03:03:10','2021-07-18 03:03:10',58,21),('2021-07-18 03:03:10','2021-07-18 03:03:10',58,23),('2021-07-18 03:03:10','2021-07-18 03:03:10',58,22);

ForeignKeyConstraintError [SequelizeForeignKeyConstraintError]: Cannot add or update a child row: a foreign key constraint fails 

그리고

단순 이 문제 해결을 넘어서 데이터 베이스 공부도 따로 하는 게 좋을까요?

답변 1

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

데이터베이스는 당연히 공부하셔야 합니다.

저 에러는 보통 foreignkey가 중복이거나 없을 때 발생하는 에러인데요. 지금 상황은 중복인 것 같습니다.

ProfileId와 HashtagId가 둘 다 겹치는 데이터가 이미 들어있을 것 같습니다.

addHashtags 대신에 setHashtags로 하면 수정될 것 같습니다.

d\/b님의 프로필 이미지
d\/b
질문자

안되는데 제가 조금만 더 찾아볼게요 ㅠㅠ 커스텀을 워낙 많이해서요..

다른 질문이 있는데 post랑 image, post랑 user 관계가 똑같은데요

post는 생성할 때 UserId 를 직접 넣어주고

image는 postId 를 왜 안넣어주는 건가요?

// Post db
static associate(db) {
db.Post.belongsTo(db.User);
db.Post.hasMany(db.Image);
// image db
static associate(db) {
db.Image.belongsTo(db.Post);
}
// user db
static associate(db) {
db.User.hasMany(db.Post);
// router
const post = await Post.create({
content: req.body.content,
UserId: req.user.id,
});
const image = await Image.create({ src: req.body.image });
await post.addImages(image);
제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

워크벤치로 데이터를 직접 보시면 중복되는 것이 들어있을 겁니다.

post.addImages할 때 PostId가 자동으로 들어갑니다.

post도 그렇게 하고싶다면 user findOne한 뒤에 user.addPost 하면 됩니다.

d\/b님의 프로필 이미지
d\/b
질문자

감사합니다!

d\/b님의 프로필 이미지
d\/b
질문자

db.Profile.hasOne(db.Image) 
db.Profile.belongsToMany(db.Hashtag , {through:"ProfileTag"})

db.Image.belongsTo(db.Profile)

db.Hashtag.belongsToMany(db.Profile, {through:"ProfileTag"})

const profile = await Profile.create({
name: name,
intro: intro,
UserId: req.user.id,
});
// if (tag) {
// const hashtags = tag.match(/#[^\s#]+/g);
// const result = await Promise.all(
// hashtags.map((tag) =>
// Hashtag.findOrCreate({ where: { name: tag.slice(1).toLowerCase() } })
// )
// );
// await profile.setHashtags(result.map(p=>p[0]));
// }
// 이미지만 우선해보려고 태그는 주석처리 하고 실행.
if (req.body.image) {
const image = await Image.create({ src: req.body.image, ProfileId: profile.id });
}

다른 자료는 저장되는데 ProfileId가 null 이네요.

profile.id 를 따로 콘솔찍어봐도 값이 null은 아닌데 데이터베이스에 올라가지 않습니다 ㅠㅠ 

 original: Error: Cannot add or update a child row: a foreign key constraint fails (`react-profiler2`.`images`, CONSTRAINT `images_ibfk_1` FOREIGN KEY (`ProfileId`) REFERENCES `hashtags` (`id`) ON DELETE SET NULL ON UPDATE CASCADE)

      at Packet.asError (/Users/jeonsiwon/WebstormProjects/profiler2/back/node_modules/mysql2/lib/packets/packet.js:712:17)

      at Execute.execute (/Users/jeonsiwon/WebstormProjects/profiler2/back/node_modules/mysql2/lib/commands/command.js:28:26)

      at Connection.handlePacket (/Users/jeonsiwon/WebstormProjects/profiler2/back/node_modules/mysql2/lib/connection.js:425:32)

      at PacketParser.onPacket (/Users/jeonsiwon/WebstormProjects/profiler2/back/node_modules/mysql2/lib/connection.js:75:12)

      at PacketParser.executeStart (/Users/jeonsiwon/WebstormProjects/profiler2/back/node_modules/mysql2/lib/packet_parser.js:75:16)

      at Socket.<anonymous> (/Users/jeonsiwon/WebstormProjects/profiler2/back/node_modules/mysql2/lib/connection.js:82:25)

      at Socket.emit (node:events:394:28)

      at addChunk (node:internal/streams/readable:312:12)

      at readableAddChunk (node:internal/streams/readable:287:9)

      at Socket.Readable.push (node:internal/streams/readable:226:10) {

    code: 'ER_NO_REFERENCED_ROW_2',

    errno: 1452,

    sqlState: '23000',

    sqlMessage: 'Cannot add or update a child row: a foreign key constraint fails (`react-profiler2`.`images`, CONSTRAINT `images_ibfk_1` FOREIGN KEY (`ProfileId`) REFERENCES `hashtags` (`id`) ON DELETE SET NULL ON UPDATE CASCADE)',

    sql: 'INSERT INTO `images` (`id`,`src`,`createdAt`,`updatedAt`,`ProfileId`) VALUES (DEFAULT,?,?,?,?);',

    parameters: [

      '스크린샷 2021-07-15 오후 2.47.02(2)____1626590614214.png',

      '2021-07-18 06:43:38',

      '2021-07-18 06:43:38',

      77

    ]

  },

  sql: 'INSERT INTO `images` (`id`,`src`,`createdAt`,`updatedAt`,`ProfileId`) VALUES (DEFAULT,?,?,?,?);',

  parameters: [

    '스크린샷 2021-07-15 오후 2.47.02(2)____1626590614214.png',

    '2021-07-18 06:43:38',

    '2021-07-18 06:43:38',

    77

  ],

  fields: [ 'ProfileId' ],

  table: 'hashtags',

  value: 77,

  index: 'images_ibfk_1',

  reltype: 'child'

}

SequelizeForeignKeyConstraintError: Cannot add or update a child row: a foreign key constraint fails (`react-profiler2`.`images`, CONSTRAINT `images_ibfk_1` FOREIGN KEY (`ProfileId`) REFERENCES `hashtags` (`id`) ON DELETE SET NULL ON UPDATE CASCADE)

------------------------------------------------------------------------------------------------

현재 상태는 위 사진과 같고 에러 메세지를 읽어보니

`images`, CONSTRAINT `images_ibfk_1` FOREIGN KEY (`ProfileId`) REFERENCES `hashtags` (`id`) ON DELETE SET NULL ON UPDATE CASCADE)',

이 부분에서 images 가 hashtag 를 참조한다고 하는 거 같은데 둘은 연관이 없는데 왜 그런지 잘

모르겠습니다 .. 

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

associate 어딘가에서 Profile이랑 Hashtag가 바뀌었습니다. 제 생각에는 예전에 잘못 설정한 것이 남아있는 것 같습니다. 테이블 지웠다가 서버 재실행해보세요.

`images`, CONSTRAINT `images_ibfk_1` FOREIGN KEY (`ProfileId`) REFERENCES `profiles` (`id`) ON DELETE SET NULL ON UPDATE CASCADE)',

여야 합니다.

d\/b님의 프로필 이미지
d\/b
질문자

네 감사합니다 ! 지우고 다시 하니 되네요

근데 밑에 두번째 사진은

TypeError: profile.addImages is not a function 라는 에러가 뜨네요 .. 

이걸 해결해야 해시테그 문제도 해결할 거 같아서요 ㅠㅠ.. 질문이 길어져서 죄송합니다 

참고로 이미지는 한장만 올리는 상태입니다.

if (req.body.image) {
const image = await Image.create({ src: req.body.image, ProfileId:profile.id});
await profile.addImages(image);
}
//실행됨
if (req.body.image) {
const image = await Image.create({ src: req.body.image});
await profile.addImages(image);
}
//오류
제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

Profile hasMany Images association있나요?

d\/b님의 프로필 이미지
d\/b
질문자

아 , 알려주신대로 하니 다 해결됐습니다.

해시태그도 다 잘 들어가고 관계도 제대로 됐네요 감사합니다 ㅠㅠ

d\/b님의 프로필 이미지
d\/b

작성한 질문수

질문하기