Chapter 10. Sibling Relationships

When adding categories to an Acronym, on duplicate requests, attach creates duplicate references. Is there a way to check if it is already attached before making an attach call? I tries isAttached() with no luck.

func addCategoriesHandler(
  _ req: Request
) throws -> Future<HTTPStatus> {
  // 2
  return try flatMap(
    to: HTTPStatus.self,
    req.parameters.next(Acronym.self),
    req.parameters.next(Category.self)) { acronym, category in
      // 3
      return acronym.categories
        .attach(category, on: req)
        .transform(to: .created)
  }
}

You can do a filter in the database - AcronymCategoryPivot.query(on: req).filter(\.acronymID == acronym.requireID()).filter(\.categoryID == category.requireID()).first() to see if that returns anything.

The other option is set up a dual key in the database, but that’s more involved and IIRC requires dropping down to raw SQL

1 Like

I took a different approach. Not sure which one is better.

extension RecipeIngredientPivot: Migration {
    static func prepare(on connection: PostgreSQLConnection) -> EventLoopFuture<Void> {
        return Database.create(self, on: connection) { builder in
            try addProperties(to: builder)
            builder.unique(on: \.ingredientID, \.recipeID)
//            builder.reference(from: \.ingredientID, to: \Ingredient.id, onDelete: .cascade)
//            builder.reference(from: \.recipeID, to: \Recipe.id, onDelete: .cascade)
        }
    }
}

Ah awesome, if that works that’s great (I’d still leave in the references). The only things to consider with that approach (which is the dual key in the database) is that you might want to catch the error if the users tries to create it, but it’s up to you