Fork me on GitHub
#fulcro
<
2022-10-08
>
Eric Dvorsak11:10:06

Has anyone worked with fulcro-rad on a pre-existing database with one-to-one relationship that are defined by a reference to the parent in the child entity table instead of the other way around? fulcro-rad would have the id of the primary address in the account table which is what cardinality ':one' expects. in this case the address table would reference the account (of course this example isn't great because because then an address can only be the primary of one account and that might not be a business constraint, but I picked an easy comparison, in practice it would simply be "extensions" to a parent entity, like user stats for instance, which wouldn't need to be in a separate table but are for separation of concern) it's essentially the same as a :many cardinality except there's a uniqueness constraint so it's expected to only get one child. The workaround would be to model it as a :many cardinality and accept having to deal with an array of 1 element, but the generated query is more complex than it needed. I'm exploring different solutions to this issue and was wondering if others have encountered this issue and have suggestions that would break as little of fulcro-rad as possible. The first thing I'm trying is to have an extra :unique? attribute to the :many cardinality although it feels wierd

Eric Dvorsak12:10:52

So I think the current solution I'm going to go with is to define the foreign key as the identity in the child table and ignore the "real" id. I used pbir/equivalence-resolver to map the identity attribute of the parent to the one of the child. The only thing that changed is that the attributes are flatten, instead of having eg [parent/attribute1 parent/attribute2 {:parent/child [parent.child/attribute1 parent.child/attribute2...]}]| I now have [parent/attribute1 parent/attribute2 parent.child/attribute1 parent.child/attribute2...]

Eric Dvorsak12:10:16

Unless I'm mistaken the cardinality • one corresponds to a many-to-one relationship where the entity where the attribute is defined is on the one side • many corresponds to a many to many relationship What I needed was to model a one to one relationship, and I feel like the solution I described above with an equivalence-resolver is sufficient Especially when using pathom3 which does a really good job at batching. In 2 queries I get both child and parent attributes. It might be possible to generate resolvers that can resolve everything in 1 query with a join if we figure out a good way to signal a one-to-one relationship

tony.kay16:10:38

The modeling in RAD can be expanded as you see fit for a particular database type and needs. Resolver regeneration is an optional thing, schema generation same, UI generation also the same. Form saves are done as diffs, but there is no requirement that how it is resolved/read from the db matches the shape of the forms. It’s all meant to be as generalized as possible so that when you find a corner case you can adapt at the layer you want.

tony.kay16:10:34

So, just because your back-end pre-exists and has a schema that RAD does not predict only means you’ll have to do a little bit of work on resolvers and perhaps save middleware. But yes, if you want auto-generated code, then you’re going to have to invent new annotations for your use case and customize the adapter

tony.kay16:10:41

I have a legacy system with RAD partially integrated, and I make multiple lists of attributes: some generate schema only, some generate resolvers only, and some are just in the all-attributes list so the UI can get to them.

Mark Wardle21:10:39

Hi all. What's the right way of initialising application state, for example, during user logout or login please? I don't want state hanging around after a session ends. I presume I can't reset to nil as that would break things, so do I a) reset to a new instantiation of com.fulcrologic.fulcro.application/fulcro-app (just like in my init fn) or b) run app/mount! with initialize-state? as true? or c) do something else?

tony.kay01:10:26

Great question. One way is to use (get-initial-state Root {}) and just swap that into the state atom, then force a render refresh.

tony.kay01:10:09

but if you’re keeping anything outside of the state atom, of course you’d have to reset that as well by hand. Another option is just to force reload the page for them on logout

tony.kay01:10:51

(.reload js/window.location true)

tony.kay01:10:54

I think would work

Mark Wardle12:10:32

Thanks @U0CKQ19AQ that's really helpful. I quite like the idea of a force reload as it will magically update if a new version is deployed on a long-running browser client (which happens a lot with shared computers in certain areas).

Mark Wardle12:10:45

If I find myself needing to preserve any state between sessions, then I'll use the former approach. Thank you!