Doubt about save() method in hasMany

Hello AdonisJs Community today I face this rare error or perhaps I am using the method save() wrong.
In the documentation says that save() method:

The save method expects an instance of the related model.
save can be applied to the following relationship types:

  • hasOne
  • hasMany
  • belongsToMany

So, when I try to do the following:

class AuditContent extends Model {
    answers() {
        return this.hasMany('App/Models/Answer')
    }

    subcontent() {
        return this.hasMany('App/Models/SubContent')
    }

    options() {
        return this.hasMany('App/Models/Option')
    }
}

With Migrations:

class OptionSchema extends Schema {
  up () {
    this.create('options', (table) => {
      table.increments()
      table.integer('audit_content_id').unsigned().references('id').inTable('audit_contents')
      table.integer('value').notNullable()      
      table.string('option')
      table.timestamps()
    })
  }
}
class AuditContentSchema extends Schema {
  up () {
    this.create('audit_contents', (table) => {
      table.increments()
      table.string('question').notNullable()
      table.enu('type',['check','range','options','description'], { useNative: true, enumName: 'typequestion' }).notNullable()
      table.timestamps()
    })
  }
}

In the seed:

const custom = await Option.createMany([ 
      {option:'Internal', value: 0 }, 
      {option:'External', value: 25 }, 
      {option:'Both', value: 50 }, 
    ])
 //Question with custom options         
      const question = new AuditContent()
      question.question = 'For system access, ¿Does it require internal or external network?'
      question.type = 'options'
      //await question.options().save(custom)
      //await question.options().saveMany(custom)

When running the seed the first option shows from the console:

TypeError: relatedInstance.save is not a function
at Proxy.save (c:\projects\practice\serverjs\node_modules@adonisjs\lucid\src\Lucid\Relations\HasMany.js:165:28)

The second option saves the row successfully.
My questions are:
Why the first option is not working?
Am I misunderstood the save method or miss something in the documentation?

Because AuditContent belongs (hasMany) to another model:

class Audit extends Model {
      questions() {
          return this.hasMany('App/Models/AuditContent')
      }      
  }
}

And in the seed I tested this, and works!:

const isoTemplate = new Audit()
    isoTemplate.isCustom = false
    isoTemplate.status = 'uninitiated'
    isoTemplate.name = 'System Audit'   
 const question = new AuditContent()
      question.question = 'For system access, ¿Does it require internal or external network?'
      question.type = 'options'
await isoTemplate.questions().save(question)

PS: The migrations are OK. It’s just the save() method that make me confused.

1 Like

Well maybe I didn’t fully get your question but why are you mixing createMany with saveMany?

Why not to just:

const question = new AuditContent()
      question.question = 'For system access, ¿Does it require internal or external network?'
      question.type = 'options'
await question.save();

await question.options().createMany([ 
      {option:'Internal', value: 0 }, 
      {option:'External', value: 25 }, 
      {option:'Both', value: 50 }, 
    ]);

The difference between createMany and saveMany is that the first one accepts POJO to create multiple instances and saveMany accepts already created instances. So no need to mix them together

3 Likes

I mix both because I have many seed to add and some of them need additional relationships, so, to save time in writing every object for every row I used both. I am sorry if I couldn’t explain very well but the error was mine, I used the save() method instead the saveMany():

const custom = await Option.createMany([ 
      {option:'Internal', value: 0 }, 
      {option:'External', value: 25 }, 
      {option:'Both', value: 50 }, 
    ])

This returned instance (which have multiple instances) cannot be inserted with the save() method. Its just that. I got the wrong idea from the following:
https://adonisjs.com/docs/4.1/lucid#_create
https://adonisjs.com/docs/4.1/lucid#_createmany

I mean:

const User = use('App/Models/User')
const userData = request.only(['username', 'email', 'age'])

// save and get instance back
const user = await User.create(userData)
const User = use('App/Models/User')
const usersData = request.collect(['username' 'email', 'age'])
 //I thought this returned instance can be used with save() method
const users = await User.createMany(usersData)

Its a novice and misunderstanding error :sweat: