2

I'm wanting to do a very quick and dirty "seed" of my database with a load of blog posts... I'm happy working with Mongo cursors etc, but can't seem to find a valid lifecycle method to "plonk" this code into... This is all for a proof of concept, so it doesn't need to be perfect!

Could someone point me in the right direction? I can't seem to access the req inside a construct method, so can't self.insert there...

jpsear
  • 43
  • 7
  • Why the downvotes? It's solid question on Apostrophe that others might value the answer to. – Tom Boutell Mar 06 '18 at 16:14
  • @TomBoutell I'm wondering if the down vote was because the topic isn't in the form of a question? I don't have the SO juice to edit this, but maybe you do? – Bob. Mar 06 '18 at 18:39

2 Answers2

3

Check out the apostrophe-tasks module. This allows you to easily add a command line task in your own module, and to easily obtain a req object with full admin privileges to do this kind of work.

Your module can call self.apos.tasks.add from within construct:

self.apos.tasks.add(self.__meta.name, 'insert-stuff', function(apos, argv, callback) {
  var req = self.apos.tasks.getReq();
  return self.find(req, { cool: true }).toArray().then(function(err, pieces) {
    if (err) {
      return callback(err);
    }
    // etc., do things with `pieces`, then invoke callback(null);
  });
};
Tom Boutell
  • 7,281
  • 1
  • 26
  • 23
0

Following on from @Tom Boutell's response, here is my final working code...

    construct: function(self, options) {
      self.apos.tasks.add(self.__meta.name, 'insert-blog-articles', function(apos, argv, callback) {
        console.info(`Running ${self.__meta.name}:insert-blog-articles`)

        if(!argv.create) throw new Error('Please pass a number of articles to create using --create=n')

        const req = self.apos.tasks.getReq()
        const numberToCreate = Array.from(Array(argv.create).keys())

        numberToCreate.forEach(item => {
          let blogPost = self.newInstance()

          blogPost = Object.assign({}, blogPost, {
            title: 'Post about cats!',
            image: 'https://www.vetbabble.com/wp-content/uploads/2016/11/hiding-cat.jpg',
            published: true,
            testData: true
          })

          self.insert(req, blogPost)
            .then(result => { console.info('Inserted doc!', result) })
          })
        })

        self.apos.tasks.add(self.__meta.name, 'show-hide-articles', function(apos, argv, callback) {
          console.info('Running task show-hide-articles', argv)

          const set = argv.show ? { published: true } : { published: false }

          self.apos.docs.db.update(
            { type: 'apostrophe-blog', testData: true },
            { $set: set },
            { multi: true }
          )
          .then(result => {
            argv.show && console.info('Docs updated, now showing posts')
            !argv.show && console.info('Docs updated, now hiding posts')
          })
          .catch(error => { console.warn('Error updating docs', error) })
        })
    }

Which (crudely) gives me two tasks:

node app apostrophe-blog:insert-blog-articles --create=100 --> create me 100 blog articles

node app apostrophe-blog:show-hide-articles --show --> Set those articles published flag to true or false, depending on the arg

jpsear
  • 43
  • 7
  • Thanks for sharing the code. You can get this code to exit properly when it's finished if you use bluebird promises: – Tom Boutell Mar 17 '18 at 13:39