How can I create a Many to Many relationship in Adonisjs?

Asked

Viewed 1,043 times

0

Well, I created a Many to Many relationship, just as I saw in the documentation, some posts and some videos on the internet, I was not successful in any attempt by some mistake of mine that I can’t identify.

The model:

Models/User.js

'use strict'

/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
const Model = use('Model')

/** @type {import('@adonisjs/framework/src/Hash')} */
const Hash = use('Hash')

class User extends Model {
  static boot () {
    super.boot()

    /**
     * A hook to hash the user password before saving
     * it to the database.
     */
    this.addHook('beforeSave', async (userInstance) => {
      if (userInstance.dirty.password) {
        userInstance.password = await Hash.make(userInstance.password)
      }
    })

  }

  /**
   * A relationship on tokens is required for auth to
   * work. Since features like `refreshTokens` or
   * `rememberToken` will be saved inside the
   * tokens table.
   *
   * @method tokens
   *
   * @return {Object}
   */
  tokens () {
    return this.hasMany('App/Models/Token')
  }

  questions(){
    return this.belongsToMany('App/Models/Question','question_id','user_id','id','id')
  }

  static get traits () {
    return [
      '@provider:Adonis/Acl/HasRole',
      '@provider:Adonis/Acl/HasPermission'
    ]
  }

}

module.exports = User

Models/Question.js

'use strict'

/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
const Model = use('Model')

class Question extends Model {

    alternatives(){
        return this.hasOne('App/Models/Alternative','id','question_id')
    }

    users(){
        return this.belongsToMany('App/Models/Users','user_id','question_id','id','id')
    }
}

module.exports = Question

The controller:

Controllers/Http/Usercontroller.js

const User = use("App/Models/User")
const Question = use("App/Models/Question")

async storeQuestion({ request, response}) {

  const {question, alternatives, user_id} = request.post()
  const questionData = await Question.create(question)

  if(alternatives){
    await questionData.alternatives().create(alternatives)
    await questionData.load('alternatives')
  }

  const user = User.find(user_id)
  await user.questions().attach(questionData)
  await user.load('questions')

  return user
}

The Migration of the pivot table:

this.create('user_creates_question', (table) => {
  table.increments()
  table.integer('user_id').unsigned().references('users.id').onDelete('cascade').index('user_id')
  table.integer('question_id').unsigned().references('questions.id').onDelete('cascade').index('question_id')
  table.timestamps()
})

When I run the route that calls this controller, the following message is returned:

user.questions is not a Function

Although the Question and Alternative entity is created, the attach function is not finished().

  • you used this tutorial: https://adonisjs.com/docs/4.0/relationships#_belongs_to_many ?

  • Yes, I have. I don’t understand why questions() aren’t a "function" :(

  • You tested that line const user = User.find(user_id) to see if a real return user?

  • Yes, all commands work until you arrive await user.questions(). attach(questionData)

  • On the model in your question can you put it complete? both?

  • 1

    Done, I tried to avoid putting everything to not get too much, but there it is.

Show 1 more comment

1 answer

1


I had a similar problem recently solved using fetch instead of load, follows suggestion.

//Seu código
await user.load('questions')

//Sugestão de alteração
user.questionData = await user.questions().fetch()

Browser other questions tagged

You are not signed in. Login or sign up in order to post.