ormadonis.jslucid

Adonis `belongsToMany` relation not working


I have the following models:

ServiceCategory:

'use strict'

const Model = use('Model')

class ServiceCategory extends Model {
  services() {
    return this
      .belongsToMany('App/Models/Service')
      .withTimestamps()
  }
}

module.exports = ServiceCategory
'use strict'

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

class ServiceCategorySchema extends Schema {
  up () {
    this.create('service_categories', (table) => {
      table.increments()

      table.string('name')
      table.string('slug').index()
      table.text('description').nullable()
      table.string('icon').nullable()

      table.boolean('is_activated').default(false).notNullable().default(true)

      table.timestamps()

      table.timestamp('deleted_at').nullable()
    })
  }

  down () {
    this.drop('service_categories')
  }
}

module.exports = ServiceCategorySchema

Service:

'use strict'

const Model = use('Model')

class Service extends Model {
  categories() {
    return this
      .belongsToMany('App/Models/ServiceCategory')
      .withTimestamps()
  }
}

module.exports = Service
'use strict'

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

class ServiceSchema extends Schema {
  up () {
    this.create('services', (table) => {
      table.increments()

      table.string('name')
      table.string('slug').index()
      table.text('description').nullable()
      table.string('icon').nullable()

      table.float('price', 10, 2)

      table.boolean('is_negotiable').default(true)

      table.boolean('is_activated').default(false).notNullable().default(true)

      table.timestamps()

      table.timestamp('deleted_at').nullable()
    })
  }

  down () {
    this.drop('services')
  }
}

module.exports = ServiceSchema

The problem is that when I try to get all ServiceCategories with their Services I just get the ServiceCategories with an empty array of services:

const serviceCategories = await ServiceCategory
      .query()
      .with('services')
      .fetch()
[
    {
      "id": 1,
      "name": "Beleza",
      "slug": "beleza",
      "description": null,
      "icon": null,
      "isActivated": true,
      "createdAt": "2019-10-21T10:43:32.000Z",
      "updatedAt": "2019-10-21T10:43:32.000Z",
      "services": []
    }
]

Intermediate table:

'use strict'

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

class ServiceServiceCategorySchema extends Schema {
  up () {
    this.create('service_service_category', (table) => {
      table.increments()

      table.integer('service_id').unsigned().index()
      table
        .foreign('service_id')
        .references('id')
        .inTable('services')
        .onDelete('cascade')

      table.integer('service_category_id').unsigned().index()
      table
        .foreign('service_category_id')
        .references('id')
        .inTable('service_categories')
        .onDelete('cascade')

      table.timestamps()
    })
  }

  down () {
    this.drop('service_service_category')
  }
}

module.exports = ServiceServiceCategorySchema

But I'm able to attach a service to a service_category:

const service = await Service.create(params)

await service.categories().attach([serviceCategoryId])

This successfully associates the service to a service category on the pivot table.

Now, why I'm able to add the relation but I'm unable to load it?


Solution

  • 'use strict'
    
    const Model = use('Model')
    
    class ServiceCategory extends Model {
      services() {
        return this
          .belongsToMany('App/Models/Service')
          .pivotTable("service_service_category")
          .withTimestamps()
      }
    }
    
    module.exports = ServiceCategory
    

    after adding pivotTable name try this one if working