Как я могу использовать родительский идентификатор для размещения дочерних данных?

avatar
蔡濡安
9 августа 2021 в 05:25
123
1
1
   final class InformationController{

    func create (_ req: Request) throws -> EventLoopFuture<Pers>{
        let perinfo=try req.content.decode(Pers.self)
        return perinfo.save(on: req.db).map {perinfo}
    }

    func putpers (_ req: Request) throws -> EventLoopFuture<HTTPStatus>  {
            let information = try req.content.decode(Pers.self)
            return Pers.find(information.$user.id, on: req.db)
                .unwrap(or: Abort(.notFound))
                .flatMap{
                    $0.name=information.name
                    $0.account=information.account
                    $0.picture=information.picture
                    $0.age=information.age
                    $0.birth=information.birth
                    $0.city=information.city
                    $0.hobby=information.hobby
                    return $0.update(on: req.db).transform(to: .ok)
                }
        }
}
final class UserController{

    func signup (_ req: Request) throws -> EventLoopFuture<User>{
            
            try User.Create.validate(content: req)
    
                // 從request body中decode出User.Create
            let newUser = try req.content.decode(User.Create.self)
                // 先檢查密碼是否==確認密碼
            guard newUser.password == newUser.confirmPassword else {
                throw Abort(.badRequest, reason: "Passwords did not match")
            }
                // 將User.Create 轉成 User
            let user = try User(account: newUser.account, password: Bcrypt.hash(newUser.password))
                // 儲存User並回傳
            return user.save(on: req.db).map { user }
        }
}

Это мой контроллер. Я использую User в качестве родителя. И Pers в детстве. Но когда я использую почтальон для выполнения API. Он продолжал говорить мне это:

enter image description here Потому что я подумал, что использование двух идентификаторов для выполнения действия немного странно. Я делаю отношение как one to many. Поскольку я не могу найти Child в области

enter image description here

маршруты:

    import Fluent
import Vapor

func routes(_ app: Application) throws {
    
    let userController = UserController()
    let informationController=InformationController()
    let passwordProtected = app.grouped(User.authenticator(),User.guardMiddleware())
    let tokenProtected = app.grouped(UserToken.authenticator(),UserToken.guardMiddleware())
    

    
    
    //修改密碼
    app.put("user",":userId", use:userController.update)//
    
    //第一次上傳個人資料
    app.post("information", use:informationController.create)//
    
    //更新個人資料
    app.put("information", use:informationController.new)
    
    //註冊
    app.post("signup", use:userController.signup)//ok
    
    //登陸
    passwordProtected.post("login",use: userController.login)//
    
    //登陸後收到個人資料
    tokenProtected.get("getperinfo",use: userController.getperinfo)//
    
    //收到他人資料
    app.get("otherperinfo",":userId",use:informationController.otherperinfo)//
    
    //登出
    app.delete("logout",":user_tokensId", use: userController.logout)//
}

родительская модель:

import Foundation
import Fluent
import Vapor
import FluentPostgresDriver


final class User:Model,Content{
    static let schema = "user"
    
    @ID(key: .id)
    var id:UUID?
    
    @Field(key:"帳號")
    var account:String
    
    
    @Field(key: "密碼")
    var password:String
    
    @Children(for: \.$user)
    var perinfo: [Pers]
    
    
    init() {}
    
    init(id: UUID?=nil, account:String, password:String){
        self.id=id
        self.account=account
        self.password=password
    }    
}

детская модель:

 import Foundation
import Fluent
import Vapor
import FluentPostgresDriver




    final class Pers:Model,Content{
        static let schema = "pers"
        
        @ID(key: .id)
        var id:UUID?
        
        @Field(key: "姓名")
        var name: String
        
        @Field(key: "IG帳號")
        var account: String
        
        @Field(key: "頭像")
        var picture: String
        
        @Field(key: "年紀")
        var age: String
        
        @Field(key: "生日")
        var birth: String
        
        @Field(key: "居住城市")
        var city: String
        
        @Field(key: "興趣")
        var hobby : String
        
        @Parent(key: "user_id")
        var user: User
        
        
        
        init(){}
        
        init(id:UUID?=nil, name:String, account:String, picture:String ,age:String, birth:String, city:String, hobby:String, userId:UUID){
            self.id=id
            self.name=name
            self.account=account
            self.picture=picture
            self.age=age
            self.birth=birth
            self.city=city
            self.hobby=hobby
            self.$user.id=userId
        }
    }
Источник
Nick
9 августа 2021 в 06:28
1

Можете ли вы отредактировать свой вопрос, указав, как вы настроили маршрут? Это не доходит до выполнения кода, который вы показали.

蔡濡安
9 августа 2021 в 08:30
0

@Nick Я добавил часть маршрутов.

0xTim
9 августа 2021 в 11:25
2

Как насчет маршрута, на который вы делаете запрос?

蔡濡安
9 августа 2021 в 11:37
0

@0xTim Эй, я обновил весь свой запрос маршрутов.

Nick
9 августа 2021 в 14:19
0

Вам также нужно что-то вроде: app.post("signup", use:userController.putpers).

蔡濡安
9 августа 2021 в 17:16
0

@Nick Извините, что мой код был недостаточно ясен. Но у меня есть API для регистрации. Теперь я обновил свой код

0xTim
10 августа 2021 в 16:08
0

Извините, я имел в виду маршрут в Postman, это последняя недостающая часть

蔡濡安
11 августа 2021 в 06:25
0

@0xTim Я добавил новую фотографию, включая мои маршруты с Content-Type и application/json

Ответы (1)

avatar
0xTim
11 августа 2021 в 13:47
2

Ваша проблема заключается в том, что вы отправляете API плоский объект JSON, пытаетесь декодировать его в модель с отношениями родитель-потомок. Оболочки свойств Fluent упрощают отображение взаимосвязей, но работают и в обратном направлении.

У вас есть два варианта:

Измените отправляемый JSON, чтобы он соответствовал ожиданиям Vapor, чтобы он выглядел примерно так:

{
  "name": "dog",
  "account": "222", 
  // ...
  "user": {
    "id": "<USER_ID>"
  }
}

Или вы можете создать DTO, соответствующий данным, которые, как вы ожидаете, клиент отправит вам, декодировать их, преобразовать в Pers и сохранить. Пример см. в репозитории Vapor TIL.

蔡濡安
12 августа 2021 в 05:44
0

хорошо, я знаю, что вы сказали. Спасибо за помощь.