themetalfleece / neogma

Object-Graph-Mapping neo4j framework, Fully-typed with TypeScript, for easy and flexible node and relationship operations
https://themetalfleece.github.io/neogma/
MIT License
124 stars 12 forks source link

Labels // Get Labels for Instance #21

Closed litewarp closed 3 years ago

litewarp commented 3 years ago

Enjoying your package so far. I'm trying to implement a schema where I have different tenants -- (i.e., Person, Person:Admin). In the past, I've used multiple labels and added instance methods on the object to return the labels so I could handle each tenant differently.

How could one go about doing that with Neogma? Ideally, the model could return all the labels from the database, but it doesn't currently. Should I define two different Models -- i.e. a "Person" that just has the sole label, and then an "Admin" that has both labels ("Person", "Admin"). Would relations defined on the base "Person" extend to the "Admin" or would I have to duplicate everything?

themetalfleece commented 3 years ago

Hello,

I'm glad that you're enjoying Neogma so far! What you're describing isn't something I have considered, so feel free to suggest what the intended functionality would be. For example, if you build a new Instance, which label(s) should it get? Same when finding nodes. Should there be an extra param?

Should I define two different Models -- i.e. a "Person" that just has the sole label, and then an "Admin" that has both labels ("Person", "Admin")

Yes, this is the only way.

Would relations defined on the base "Person" extend to the "Admin" or would I have to duplicate everything?

You would have to repeat everything, for example use the same object/functions for each model.

litewarp commented 3 years ago

Thanks for the quick reply!

I think the easiest solution would be an instance method to return the labels for a model. So, here you already have access to the labels from the record (node.labels). So you could store it by assigning node.labels to a instance property here either as a public property, .e.g this.labels or as a private property with an instance method getLabels()

Doing so would allow me to use one model to retrieve results from the backend and then administer different tenants on the graphql layer by checking the labels.

themetalfleece commented 3 years ago

Thanks for the quick reply!

I think the easiest solution would be an instance method to return the labels for a model. So, here you already have access to the labels from the record (node.labels). So you could store it by assigning node.labels to a instance property here either as a public property, .e.g this.labels or as a private property with an instance method getLabels()

Doing so would allow me to use one model to retrieve results from the backend and then administer different tenants on the graphql layer by checking the labels.

Just a question so I can understand this more, would this implementation offer more than just creating a method which calls the Model.getRawLabels() static (which just returns the labels used in the schema declaration)? Since finding a node always uses the Model's labels.

litewarp commented 3 years ago

Yes. So it's more than the labels returned by the schema. It's the actual labels used by the returned result node. That way I can define the model with one label (Person) but have it also return any other labels on that person.

This way I don't have to define overlapping and redundant models. I can define just the Person and then deal with different use cases in the GraphQL layer -- ie if person has the label "Admin" I could filter the sub graph

themetalfleece commented 3 years ago

Please let me know if my implementation covers your needs. I've added a labels public attribute for Instances, which has the actual labels of a Node from the QueryResult. They are set by using the new Model.buildFromRecord static, which is now used internally in Neogma. It can also be used externally, it just needs a record from a QueryResult.

buildFromRecord doc. labels doc.

Deployed in 1.9.0.