Closed kevinresol closed 8 years ago
Is it possible to automatically fetch the profile field (through some remoting behind the hood) when the templating engine needs it? And only when all the required fields are ready, it does the actual rendering.
Another idea, is it possible to keep a global cache of the database objects?
For example, currently when user.profile
or profile.user
is accessed, under the hood it fetches a the corresponding object using manager.get()
or select()
and it is cached in the object (which does the fetching) itself. So it will cause circular reference when HasOne
and BelongsTo
are also serialized. (i.e. user.profile
creates a new profile object and profile.user
creates a new user object which in turn creates a new profile object again) The problem could possibly be solved if we can keep a global cache of the User and Profile objects so Serializer.USE_CACHE
can handle them without causing circular reference?
So I've been coming back to this issue.
The global cache idea is what I was trying to do with ufront-clientds, but I'm not using it anymore - it was kind of cool in theory, but in practice code got very very messy very quickly. Each request for an object is asynchronous, so returns a Future (in fact, clientds used the HxPromise library instead). This led not only to callback hell, but also to confusion: should user.groups
be cached synchronously, or should it be a property that returns a Future? At the job where I used that we ended up moving away from using it wherever possible.
The better solution, that I'm suggesting now, is that we use UFApi remoting, but have an easy way to specify if relationships should be included in the serialization.
The first step I've just implemented in Ufront-ORM
hxSerializationFields
array:userProfile.hxSerializationFields.push( "user" ); // Include a BelongsTo<User> property
userProfile.user.hxSerializationFields = ["username","groups"]; // Include the ManyToMany<User,Group>
return userProfile;
In future I'll attempt a macro like...
return BlogPost.manager.all().alsoWithFields([ author, author.name, author.id, tags[].name ]);
return BlogPost.manager.all().onlyWithFields([ title, url, author.name, author.id, tags[].name ]);
return User.manager.all().withoutFields([ password, salt ]);
...that is a type safe way of modifying hxSerializationFields
on the relevant objects so you can easily pick which fields to return in your API.
Thoughts?
I didn't used ufront-orm for some time because I am using nodejs + mongoose at the moment. So I don't really have much comment on this right now, please feel free to modify if you see it appropriate.
Okay, no worries :) I'll close this issue and track progress at:
The above code works at server side but not only client side because
profile
is a getter function but not real property thus not included in the serialized string sent to the client. (souser.profile
is null at client side)I tried to hack into
DBMacros.hx
andObject.hx
to make it serialize HasOne & BelongsTo as well. But that seems to lead to a circular reference (stack overflow) because User HasOne Profile BelongsTo User HasOne Profile BelongsTo User.......