Dependent Entities
It's unlikely that we're building an application that deals solely with users, let's be super imaginative and say we're building a.... revolutionary blogging platform! We'll add a post
factory:
To switch things up a little, posts are identified by a uuid, so we can use clojure core's random-uuid
function to generate one. Posts also have a title
, some content
, and an author
. It's here we meet our next directive: one
.
The one
directive tells fabrikk that the current entity depends on an entity built by another factory. In this case we've given it the id of our user factory (which we mentioned in Factories & Building), so when we build a post, it'll automatically build a user:
... and nest the full user entity under the author key. There are some cases where we'd want to do this - the entity we're creating might have some complex sub structures - but in general this isn't what we want. Our users and our posts will probably be stored as two separate entities in our database layer, and we'll reference them by id. A small tweak to the user factory solves this:
Fabrikk doesn't make any assumptions about what key identifies a user, so you can tell it to identify them by their id
by specifying a primary-key
. Now let's try bulding another post:
So now we're referencing something that looks like a user id, but where's the user? Let's introduce our first output option:
Output options are a third optional argument to build
(and related functions), in this case we're not supplying any build options so our second argument is an empty hash.
There's our missing user! It's here that I reveal that the output of (fab/build post)
gives you an entity map with a build graph hiding in the metadata. The build graph keeps track of the entities that the output depends on, and the build-order
option outputs a reverse topological sort of that graph.
We can take a look at the build graph by getting the metadata of a post:
Yikes! There's a lot going on there, but you shouldn't need to worry about these details. This might not seem very useful yet, but it will be soon when we talk about using Fabrikk to persist the entities it builds.
What happens when we want a list of posts? We use the build-list
function, this function has an almost identical signature to build
, with the addition of a quantity argument to specify how many entities you'd like to build.
We can see here that Fabrikk has created a new user for each post. If you want the same user for each post you need to be explicit about it:
Here we can see that build-list
accepts the same build and output options as build, and since we're using the build-order output, we can see that both posts will share the same user.
A final note for this section: even though we've used the one
directive in the post factory, the relationship we're describing isn't between the factories. All we're saying is that the default representation of a post requires that a user be created. We're free to override that if we wish:
No user was created here because we overrode the author
key to be a plain string.
We can also add additional entities to the factory at will. Here we'll add an extra editor
user to the post:
and we get a distinct user as an editor of the post.
Last updated