Afficher ou sauvegarder une relation dans la bdd

Bonjour,

J’ai repris une partie du cours vapor 4 pour la partie User, ensuite j’ai crée une table category et un user peut crée plusieurs catégories et il vois que c’est catégories qu’ils à créent jusque la tout va bien.

pour qu’un user enregistre une catégorie il faut que je le json sois comme ça :

 {
	"name" : "travail5",
	"user": {
		"id": "48886976-57F4-4B1E-A08D-107A8953FECE"
	}
}

ma function create dans le controller categorie

func create(req: Request) throws -> EventLoopFuture<Category> {
       let user = try req.auth.require(User.self)
         let category = try req.content.decode(Category.self)
        return category.save(on: req.db).map { category }
    }

tout fonctionne bien par contre je ne trouve pas logique que nous sommes obligé de mettre le user id dans l’envoi de la requête car nous l’avons dans la variable user.

J’ai essayer ceci :

        let user = try req.auth.require(User.self)  
        let data = try req.content.decode(Category.self)
        let category = Category(name: data.name, userID: user.id! as UUID)
        return category.save(on: req.db).map { category }

mais cela ne fonctionne pas il me dit Value of type 'User' required for key 'user'
je pense que j’utilise mal cette méthode mais je ne vois pas trop la solution.

Ensuite pour afficher les catégories d’un user j’ai fait comme ceci :

func index(req: Request) throws -> EventLoopFuture<[Category]> {
        let user = try req.auth.require(User.self)
        return user.$categories.load(on: req.db).map{ user.categories}
    }

Il y a une autre solution pour afficher les catégories d’ user ?

@mbritto il y aura une mise à jour du cours vapor avec des choses un peux plus complexe ?

Merci;

J’ai trouvé 2 solution pour mon premier problème la premier crée une struct CreateCategoryData comme ceci :

struct CreateCategoryData: Content {
  let name: String
  let userID: UUID
}

La fonction create:

func create(req: Request) throws -> EventLoopFuture<Category> {
       let user = try req.auth.require(User.self)
        
        let data = try req.content.decode(CreateCategoryData.self)
        
        let category = Category(name: data.name, userID: data.userID)
        return category.save(on: req.db).map { category }
    }

ce qui donne dans le json d’envoi

{
	"name" : "travail9",
        "userID": "qsdjkqsmdldn"
}

Ensuite il y a la deuxième solution qui est d’utiliser les informations qui se dans le user car nous avons déjà les informations de l’id dans let user = try req.auth.require(User.self)

voici ma struct CreateCategoryData :

struct CreateCategoryData: Content {
  let name: String
}

ma fonction create :

func create(req: Request) throws -> EventLoopFuture<Category> {
       let user = try req.auth.require(User.self)
        
        let data = try req.content.decode(CreateCategoryData.self)
        
        let category = Category(name: data.name, userID: user.id! as UUID)
        return category.save(on: req.db).map { category }
    }

voila :slight_smile:

@mbritto pourrais quand tu as 5 min me faire un petit retour sur mes solutions stp

merci

Effectivement c’est souvent une bonne solution de créer ta propre structure pour déclarer ton format de JSON en entrée. Ca te permet d’avoir un JSON plus simple et de ne demander que le nécessaire.
Ensuite, une fois que tu as converti ton JSON tu peux utiliser tes variables pour créer les objets de ton choix.
En plus, en bonus tu diminues ton couplage : si tu changes un jour tes objets User et Category, ton JSON reste intact :+1:
En tous cas c’est comme ça que je travaille.