Server Side Swift with Vapor - Part 13: Sibling | Ray Wenderlich

Learn how to set up sibling relationships in Fluent and how to set up queries to retrieve model's siblings.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/4493-server-side-swift-with-vapor/lessons/13

Hmmm… I seem to be getting an error when performing the POST request “/api/acronyms/1/categories/1”

[ ERROR ] FluentError.modelNotFound: No model with ID 1 was found (Model.swift:267)

And then it blocks any more requests from hitting the server. I’ve used the downloadable material to make sure it wasn’t an error on my end. Any ideas on this?

Thanks!

-brian

edit: I got it working with the downloaded material, actually. It seems to do this when I switch from FluentSQLite to FluentMySQL

@briancorbin yeah it’s a known issue with the MySQL beta - tracked here multiple query start same time · Issue #60 · vapor/fluent-mysql-driver · GitHub

The work around is to not do the dual flatMap - do the req.parameter calls separately in their own flatMap

@0xtim ah, thanks for the quick response. Thought that might be the case. Was just hoping I could make it look nice and neat, but I suppose I can wait.

Do you know if this causes any inefficiency in database lookup time, or is it just syntactic sugar? New to Vapor and Fluent, so I haven’t taken a look at the inner workings of everything yet.

Thanks again!

@briancorbin it shouldn’t cause any slowdowns - the DB still has to do two queries at the end of the day. It’s just to reduce nesting and made the code read better. All these weird bugs should hopefully be fixed by Swift NIO when that gets merged soon.

@0xtim: Thanks for the tip about dual flatMaps. I switched the database to MySQL and ran into the same error that @briancorbin reported. The following code seems to work fine. Is there a better way to do it (at least until the bug is fixed!)?

func addCategoriesHandler(_ req: Request) throws -> Future<HTTPStatus> {
  return try req.parameter(Acronym.self).flatMap(to: HTTPStatus.self) { acronym in
    return try req.parameter(Category.self).flatMap(to: HTTPStatus.self) { category in
      let pivot = try AcronymCategoryPivot(acronym.requireID(), category.requireID())
      return pivot.save(on: req).transform(to: .ok)
    }
  }
}

Thanks for a great tutorial series!

@rcasey I think that’s probably the best way until the bug is fixed I think! Shouldn’t be too long until the fix is in

@0xtim everytime I’m making the following request:
http://localhost:8080/api/acronyms/1/categories/

I get the following response:

{
“error”: true,
“reason”: “Could not convert to String: 5A67E987-29F6-4FC9-AB26-87D1ACBA1151”
}

I tried downloading the source for the session, but the same issue persist. Do you have a solution for this :slight_smile: ?

I’m getting the same issue, which leads me to think it has to do with recent Vapor changes rather than we both made the same error, but I could be wrong!

Here’s the debug:

[ ERROR ] SQLiteError.warning: Could not convert to String: 48438519-48AD-4437-AAAD-6DF56CBFA4BB (SQLiteData.swift:177)

@grumme @amyerson ah the joys of working with a beta software! I know there are some decoding changes that have happened, I’ll dig in and see if they are related

@grumme @amyerson there’s a regression in SQLite in the current RC - issue is here Unable to convert UUID to String · Issue #32 · vapor/sqlite-kit · GitHub

If you continue on and switch to using MySQL then the categories work again

Thanks for the quick reply @0xtim , as usual :-).

But if I change to MySQL, I’m getting this error: MySQLError.prepareStatus: Prepare response has invalid status · Issue #1569 · vapor/vapor · GitHub

Hmm that’s weird - I’m wondering if the database decoding has gotten messed up. Can you try resetting the database and starting again?

docker stop mysql
docker rm mysql
docker run --name mysql -e MYSQL_USER=til -e MYSQL_PASSWORD=password -e MYSQL_DATABASE=vapor -p 3306:3306 -d mysql/mysql-server

Switching to MySQL for 3.0.0-rc.2 worked perfectly. SQLite still throwing errors for converting UUID to string.

@thecb4 yep the issue on GitHub tracking this is

@0xtim I had the same issue and currently Im trying to switch to MySQL. I followed https://docs.vapor.codes/3.0/mysql/fluent/ to do so. However I’m getting this error :confused:

connectFailed(NIO.NIOConnectionError(host: “localhost”, port: 3306, dnsAError: nil, dnsAAAAError: nil, connectionErrors: [NIO.SingleConnectionFailure(target: [IPv6]localhost:3306, error: finishing a non-blocking connect failed), NIO.SingleConnectionFailure(target: [IPv4]localhost:3306, error: finishing a non-blocking connect failed), NIO.SingleConnectionFailure(target: [IPv6]localhost:3306, error: finishing a non-blocking connect failed), NIO.SingleConnectionFailure(target: [IPv4]localhost:3306, error: finishing a non-blocking connect failed)]))
Program ended with exit code: 1

@deor is your Docker container running?

@0xtim Yeah, everything is running now :slight_smile: thanks for help

1 Like

I’m using Vapor 3.0.3, and I’m getting the following error when trying to list categories on an acronym, or acronyms on a category:

“Could not convert to Int: 03C7CA42-332F-4411-9DA6-31E7F369CED1”

the UUID is that of my AcronymCategoryPivot object (it appears correctly set up in the database). If I switch to an Int ID for the pivot objects (and switch to conforming to SQLitePivot instead of SQLiteUUIDPivot), it all works fine.

Hi @bengottlieb unfortunately that’s a known issue in SQLite at the moment which I’m waiting to be fixed. The workarounds are to use Int as you’ve discovered or switch to MySQL earlier