fliend createdAt in Prisma schema returns a null value when createUser() is called - mongodb

When including a createdAt field in my datamodel.prisma schema the DateTime! returns a null value.
I am raising this on here so that if anyone else has the same problem, hopefully they will be able to find this post.
// in datamodel.prisma
type User {
id: ID! #id
trade_no: String!
name: String!
email: String!
createdAt: DateTime!
}
Error message looks like this "Reason: 'createdAt' Expected non-null value, found null."

In mongoDB the createdAt must be written as
type User {
id: ID! #id
trade_no: String!
name: String!
email: String!
created_at: DateTime! #createdAt
}
when used with Prisma (don't know if this is the case for other databases). Also, bear in mind that the #relation directive must have link: INLINE as an argument (the relationship is stored in the record, not in a separate table). Took me a while to work this out so I thought I'd put it here.
It's worth having a look at https://www.prisma.io/docs/releases-and-maintenance/features-in-preview/mongodb-b6o5/ for other specificities with Prisma & mongoDB.

Related

How to get a property of a tuple with a string?

I'm starting in Swift, I come from JavaScript, and some things are a bit confusing for me, is there something similar to this in Swift?:
JS:
var user = {name: "Chris Answood"}
user["name"]
JavaScript doesn't have built-in tuple support. You just created an object and get the value of the name property inside this object. You have used user["name"] but user.name would also be possible.
To achieve this in Swift you can create a struct:
struct User {
name: String
}
let user = User(name: "Chris Answood")
print(user.name)
Unlike JavaScript, Swift has support for tuples. This is an easy example:
let user = (firstName: "Chris", lastName: "Answood")
print(user.firstName)

How do I combine 'nil' and an !Included datatype?

I am defining a RAML 1.0 datatype with property that can be 'nil.' The type of that property is an !included datatype which, whilst not giving any errors in the datatype definition causes the root object to throw a "Unresolved reference '!includereference-data.raml' at libraries/types/personal-details.raml (10, 12)'
I've tried converting the DataType to a library to try and implement a "uses" or "types" but that impacts all the other objects that include this data type.
#%RAML 1.0 DataType
properties:
DateOfBirth: datetime
FirstName: string
FamilyName: nil | string
PreferredName: nil | string
PreviousNames: nil | string
Title: !include reference-data.raml
Gender: nil | !include reference-data.raml
The 'Title' property is working as expected, the error is thrown against the Gender property - I actually want both to be nillable.
The datatype to hold nillable properties here is "name_block.raml"
#%RAML 1.0 DataType
uses:
lib: base_types.raml
type: object
properties:
FirstName: lib.string30
MiddleName: lib.nstring30
LastName: lib.string150
The included library (base_types.raml) is defined as
#%RAML 1.0 Library
types:
string30:
type: string
minLength: 0
maxLength: 30
string150:
type: string
minLength: 0
maxLength: 150
nstring30:
type: string | nil
If anyone knows of a better way - It would be great to see it.

go mongodb driver and struct, find messes with uppercase and lowercase

var Messages []Token
c2 := session.DB("mydatabase").C("pages")
query2 := c2.Find(bson.M{}).All(&Messages)
fmt.Print(Messages)
Here's the structure in my Mongo DB:
id_
pageUrl
token
pageId
I first tried the structure as this:
type Token struct {
PageUrl string
Token string
PageId string
}
but only the token was being printed, perhaps because it's all lowercase. The other two fields were not being retrieved because they contain uppercase. Then I tried this:
type Token struct {
PageUrl string `json: "pageUrl" bson: "pageUrl"`
Token string `json: "token" bson: "token"`
PageId string `json: "pageId" bson: "pageId"`
}
what are those bson and json things? I've only put it there because I've seen in the internet, but it doesn't work, I still get only the token field
UPDATE with solution and tested example for nested documents
I've seen that there was no posts regarding this question so remember that the solution was to remove the spaces between json: and bson:
Also, to help someone who might be wondering how to do it for nested structs, here I give two structures that worked for me:
type Token struct {
PageUrl string `json:"pageUrl" bson:"pageUrl"`
Token string `json:"token" bson:"token"`
PageId string `json:"pageId" bson:"pageId"`
}
type Message struct {
Sender struct {
Id string `json:"id" bson:"id"`
} `json:"sender" bson:"sender"`
Recipient struct {
Id string `json:"id" bson:"id"`
} `json:"recipient" bson:"recipient"`
Message struct {
Mid string `json:"mid" bson:"mid"`
Seq int `json:"seq" bson:"seq"`
Message string `json:"text" bson:"text"`
}
}
these json and bson stuff is called tags
My best guess is that because Go requires a variable or function to be public by Capitalize the first character, so serialize frameworks like json or bson require the struct Capitalize its first character to expose the field(so that it could see the field). Thus the exposed field name should be defined with a tag (to avoid the restriction).
the space between bson: and "token" seems to have cause the problem
I tried following code snippet and seems works fine.
type Token struct {
PageUrl string `json:"pageUrl" bson:"pageUrl"`
Token string `json:"token" bson:"token"`
PageId string `json:"pageId" bson:"pageId"`
}

Anonymous structs return empty field value

type (
Id struct {
// I previously forgot to add the `ID` field in my question, it is present in my code but not on this question as #icza pointed it out to me
ID bson.ObjectId `json:"id" bson:"_id"`
}
User struct {
// When using anonymous struct, upon returning the collection, each of the document will have an empty `id` field, `id: ""`
Id
Email string `json:"email" bson:"email"`
...
}
// This works
User2 struct {
ID bson.ObjectId `json:"id" bson:"_id"`
Email string `json:"email" bson:"email"`
}
)
I might not have fully understood the concept of anonymous structs yet. In the example above, when querying all users from a collection, the id field is going to be an empty string "". However, if I directly define the ID field in the User struct, the id shows up fine. Is this not what anonymous structs are for? Basically extending struct so you won't have to type them again and again?
More example:
type SoftDelete struct {
CreatedAt time.Time `json:"created_at" bson:"created_at"`
UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`
DeletedAt time.Time `json:"deleted_at" bson:"deleted_at"`
}
type UserModel struct {
SoftDelete
}
type BlogPost struct {
SoftDelete
}
The problem here is that fields having struct types (including embedded structs) appear as embedded documents in MongoDB. If you don't want this, you have to specify the "inline" bson flag when embedding a struct:
User struct {
Id `bson:",inline"`
Email string `json:"email" bson:"email"`
}
What the "inline" tag does is in MongoDB it "flattens" the fields of the embedded struct as if they were part of the embedder struct.
Similarly:
type UserModel struct {
SoftDelete `bson:",inline"`
}
type BlogPost struct {
SoftDelete `bson:",inline"`
}
Edit: the following section applies to the original Id type which embedded bson.ObjectId. The asker later clarified that this was just a typo (and edited the question since), and it is a named, non-anonymous field. Still think the info below is useful.
One thing to note about your Id type: Your Id type also embeds bson.ObjectId:
Id struct {
bson.ObjectId `json:"id" bson:"_id"`
}
Id not just has a field of bson.ObjectId, but it embeds it. This matters because this way you Id type will have a String() method promoted from bson.ObjectId, and so will User which embeds Id. Having said that, it will be hard trying to print or debug values of type User, because you will always see it printed just as a single ObjectId.
Instead you can make it a regular field in Id, embedding Id in User will still work as expected:
Id struct {
ID bson.ObjectId `json:"id" bson:"_id"`
}
See related question+asnwer: Enforce a type mapping with mgo

Variable Naming Convention Thoughts for Swift 3

Concerning Variable Names:
Suppose there is some code similar to the following:
class AgentModel
var name: String?
var office: String?
var phone: String?
Would naming-convention dictate that these be named as
class AgentModel
var nameString: String?
var officeString: String?
var phoneString: String?
I haven't been able to find if Apple definitively lays out guidelines for whether one practice is preferred or not, but it doesn't seem Swift-y to always follow the latter, except when necessary.
Concerning Object Names: Similarly, should the object even be named
AgentModel
or should it be named as follows?
Agent
At first glance, I would think that this would follow the same conventions. Am I correct, or would this be an exception to the rule?
Do people have thoughts and/or references for this?
Thanks!
The API Design Guidelines on swift.org state (emphasis added):
Omit needless words. Every word in a name should convey salient information at the use site.
More words may be needed to clarify intent or disambiguate meaning, but those that are redundant with information the reader already possesses should be omitted. In particular, omit words that merely repeat type information.
And:
Name variables, parameters, and associated types according to their roles, rather than their type constraints.
So
var nameString: String?
var officeString: String?
var phoneString: String?
is clearly not recommended.
var name: String?
var office: String?
var phone: String?
is good but may be improved further, such as using phoneNumber
instead of phone.
No.
If I needed to know the type and it wasn't obvious from context, I would just option click it and Xcode will give me its declaration, including its access specifier, type and mutability.
class AgentModel {
var name: String?
var office: String?
var phone: String?
}
let agent = AgentModel()
agent.name = "EndersJeesh"
agent.office = "London Port"
agent.phone = "180059345345"
This will make life easy. Since the type is already specified in variable declaration "var name: String?" it won't makes sense to add the type in the variable name again.