Giter Club home page Giter Club logo

Comments (5)

jesstelford avatar jesstelford commented on May 10, 2024

I'm going to do this by leveraging the where clauses:

keystone.createItems({
  Users: [{
    name: 'Jess',
  }],
  Posts: [{
    title: 'Hello world',
    author: {
      where: {
        name: 'Jess',
      }
    }
  }],
});

The config tells us that the Posts.author field is a Relationship, so we can then safely extract out the where clause before we do the INSERT into the DB.

Once we have the where clause, we can do the lookup, and then make the relationship connections.

One caveat: If Posts.author is set as required, the initial insert would fail (because the Posts.author value is null until after the insert). So we need to bypass that required check when doing the initial INSERT.

from keystone.

JedWatson avatar JedWatson commented on May 10, 2024

That's a pretty cool approach. What we used to do in Keystone 4 was:

keystone.createItems({
  Users: [{
    name: 'Jess',
    _ref: 'jess',
  }],
  Posts: [{
    title: 'Hello world',
    author: 'jess'
  }],
});

Create the items, keep the refs as we create them (resolve to ids) then do a second pass updating the relationships.

Definitely important to at least keep the two-pass approach; I like the idea of being able to do any where clause when creating relationships, but if we didn't have a unique (known) value to filter them on, maybe bringing back the idea of a manual ref linking system could help.

The v4 implementation is actually reasonably well written for old code, if you want to check it out: https://github.com/keystonejs/keystone/blob/master/lib/core/createItems.js

It did some nice stats collection too, which we logged out to the console when it was executed as part of an upgrade script.

from keystone.

JedWatson avatar JedWatson commented on May 10, 2024

Two other ideas: your approach works well for resolving data that already exists; from memory, we had an alternative way of doing it where you'd basically have to query the database first then provide a function that resolved to itemIds...

Maybe there's some nice futuristic es syntax stuff we could take advantage of here? we could generate ref IDs and resolve their values like this:

const { ref } = require('@keystonejs/create-items');
keystone.createItems({
  Users: {
    [ref('jess')]: {
      name: 'Jess',
    },
  },
  Posts: [{
    title: 'Hello world',
    author: ref('jess'),
  }],
});

Just thinking 🤔

from keystone.

jesstelford avatar jesstelford commented on May 10, 2024

Definitely important to at least keep the two-pass approach

💯% - it's the approach I've taken, and it looks to be working really well, here's how the code shakes out:

// 1. Split it apart
const { relationships, data } = unmergeRelationships(this.lists, itemsToCreate);
// 2. Create the items
const createdItems = await createItems(data);
// 3. Create the relationships
const createdRelationships = await createRelationships(
  this.lists,
  relationships,
  createdItems
);
// 4. Merge the data back together again
return mergeRelationships(createdItems, createdRelationships);

if we didn't have a unique (known) value to filter them on, maybe bringing back the idea of a manual ref linking system could help.

Agreed! Do you have any specific examples so I can form some tests around them? I was thinking of also enabling the filter/first/skip filtering options as well as the where clause, but can't really think of a usecase for that either (I don't have enough experience with this kind of data modelling yet).

we could generate ref IDs and resolve their values like this:

Oooh, that's a really nice direction! I wonder how that plays into the usecase where only some items are ref'd?

const { ref } = require('@keystonejs/create-items');
keystone.createItems({
  Users: [
    [ref('jess')]: { // INVALID SYNTAX (within an array)
      name: 'Jess',
    },
    {
      name: 'Jed',
    },
  ],
  Posts: [{
    title: 'Hello world',
    author: ref('jess'),
  }],
});

from keystone.

jesstelford avatar jesstelford commented on May 10, 2024

Oh, maybe it's like this?

const { ref } = require('@keystonejs/create-items');
keystone.createItems({
  Users: [
    ref({
      name: 'Jess',
    }, 'jess'),
    {
      name: 'Jed',
    },
  ],
  Posts: [{
    title: 'Hello world',
    author: ref('jess'),
  }],
});

from keystone.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.