Open gaetanm opened 7 years ago
@gaetanm why do you need to apply both attributes on the same property? why not have two properties one for the user relationship & the other for user-id?
class Menu: Resource {
var nbrOfRecipes: Int?
var userID: String?
var user: User?
Perhaps you could provide an example of your response JSON to make it clear?
I don't know enough about how Spine works internally to know that it was possible to use 2 properties for the same JSON data. Interesting!
About the JSON response, it's like this:
"data": {
"id": "4",
"type": "menus",
"attributes": {
"nb-recipes": 4,
"created-at": "2016-11-27 19:50:07",
"user-id": 1
}
By using 2 properties like you showed me, I now have an assertion failure:
Resource of type menus does not contain a field named user-id
My query is:
var query = Query(resourceType: Menu.self)
query.whereAttribute("user-id", equalTo: userID!)
My class is now:
class Menu: Resource {
var nbrOfRecipes: Int?
var user: User?
var userID: String?
var recipes: LinkedResourceCollection?
override class var resourceType: ResourceType {
return "menus"
}
override class var fields: [Field] {
return fieldsFromDictionary([
"nbrOfRecipes": Attribute().serializeAs("nb-recipes"),
"userID": Attribute().serializeAs("user-id"),
"user": ToOneRelationship(User.self),
"recipes": ToManyRelationship(Recipe.self)
])
}
}
It's really a black box for me. Do I have this error because of those 2 properties?
to resolve the error:
Resource of type menus does not contain a field named user-id You'll need to pass the class property name into the query:
query.whereAttribute("userID", equalTo: userID!)
Spine will perform the appropriate transform/formatting from property name to field name as described in
serializeAs()
.
@gaetanm please see examples on http://jsonapi.org/ for how relationships
responses should look. I think your JSON should look more like this:
"data": [{
"id": "4",
"type": "menus",
"attributes": {
"nb-recipes": 4,
"created-at": "2016-11-27 19:50:07",
},
"relationships": {
"user": {
"data": { "type": "users", "id": "1" }
},
}
}],
"included": [{
"type": "users",
"id": "1",
"attributes": {
"first-name": "Dan",
"last-name": "Gebhardt",
},
Which includes the relationships
properties & also the associated included
object
Without needing the additional user-id
attribute, you can access this data through the Resource
relationship data: https://github.com/wvteijlingen/Spine/blob/master/Spine/Resource.swift#L104
Whether your associated User has been included or not.
Thanks, it's more clear now.
I have a last error message:
'[<DoEat.Menu 0x6100002e4b80> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key nbrOfRecipes.'
No clue about why I have that error. I already had a similar error message in the past but it was caused by the storyboard, which seems to not be the case here.
@gaetanm nbrOfRecipes
must be a NSNumber
. see documentation for using primitive types
You will understand just by looking at my class:
As you can guess, this result in a
fatal error: Dictionary literal contains duplicate keys
.How to do to apply both
ToOneRelationship(User.self)
andAttribute().serializeAs("user-id")
on the same attribute?