I have a one-to-many
Ontology relationship where -- for a given Alert
object-instance -- I want at most one Feedback
object-instance for it per User
. A Feedback
object-instance is Created & Updated by Users
using its Add & Modify Actions, respectively (and is used to provide one feedback score & commentary per User
per Alert
object-instance).
As such, to implement at most one semantics, each Feedback
object requires a Primary Key
composed of:
feedbackID
(PK) =alertID
(PK) +userID
(PK)
However, in its backend definition, the Feedback
object-type's Add Action sets the Primary Key
as a UUID
, and this cannot be overwritten once instantiated. (Note: An object-reference
or property
is also possible here, but either would also only be part of the composite key
sought). That is to say, although it's possible to synthesize the above composite-key
in a frontend Workshop Action Tab
(using Workshop
variables
and forms
), it's understandably not possible to overwrite an object's already-existing PK
with it.
Indicentally, for completeness, I'll mention, but not necessarily recommend, a two-DataSet option for
composite-key PK
consisting of the following steps:
- The Add Action creates rows for an initial DataSet with
UUID
's as itsPK
.- A Foundry
data pipeline
mirrors this DataSet to create a corresponding DataSet withalertID
+userID
as itsPK
.- And finally, the Modify Action as well as downstream application uses consume that mirror (second) DataSet.
Again, presented for completeness and not necessarily recommended since it duplicates DataSets, as well as adds propagation delay to the out-of-the-box platform propagation delay.
With that as preamble, is there a just-in-time technique to generate Objects with a composite-key PK
consisting of properties from other Objects (again, at Add
-Action click time)? I may have missed something. Thank you.
I came up with an interim workaround which broadly include these steps:
Function
(snippet below) coupled with a Function-backed Workshop variable
that returns a count of Feedback
objects having the same alertID
and userID
combination (i.e. a manually synthesized composite-key
):
- If
0
is returned, only the Add Action Button (in green) is visible (via display logic).- If
1
is returned, only the Modify Action Button (in amber) is visible (via display logic).- If
> 1
is returned (which would only happen if a bug existed somewhere), only a Red Error Button is visible (via display logic), with its hover-over text instructing the user to take a screenshot and eMail developers. No Action or Event is attached to this button.
@Function() // Used to set a Workshop variable (0|1|>1).
public async countFeedbackRecords(alertID: string,
userID: string):
Promise<Integer> {
const feedbacks = Objects.search().feedback() // Feedback object-type is imported at top-of-file.
const count = await feedbacks.filter(obj => obj.alertId.exactMatch(alertID))
.filter(obj => obj.user.exactMatch(userID))
.count()
return Promise.resolve(count || 0)
}
One downside to this approach are lookups against the two columns mentioned, which are neither hashed nor indexed.