Skip to content

Delete attached BelongsToOneRelation relations with upsertGraph #964

@hugomallet

Description

@hugomallet

Hi,

I am trying to delete a belongstoone relation using upsertgraph method
For example, starting with this model (using belongstoonerelation) :

parent: { id: 1, child: { id: 'c1' } }
upsertGraph(parent, { insertMissing: ['child'] })

Then, if i remove the child from parent :

parent: { id: 1 }
upsertGraph(parent)

Then child stills exists (and is still related to parent).
I would expect child to be completely removed from database.

Here is a full example that reproduces the problem :

const { Model, knexSnakeCaseMappers } = require('objection');
const Knex = require('knex');

const knex = Knex({
    client: 'sqlite3',
    useNullAsDefault: true,
    connection: {
        filename: 'example.db'
    },
    pool: {
        afterCreate: (conn, cb) => {
            conn.run('PRAGMA foreign_keys = ON', cb);
        },
    },
});

Model.knex(knex);

class Address extends Model {
    static get idColumn() {
        return 'city';
    }
    
    static get tableName() {
        return 'addresses';
    }
}

class Person extends Model {
    static get tableName() {
        return 'persons';
    }
    
    static get relationMappings() {
        return {
            address: {
                relation: Model.BelongsToOneRelation,
                modelClass: Address,
                join: {
                    from: 'persons.addressId',
                    to: 'addresses.city'
                }
            }
        };
    }
}

async function createSchema() {
    await knex.schema.dropTableIfExists('persons');
    await knex.schema.dropTableIfExists('addresses');
    
    await knex.schema.createTable('addresses', table => {
        table.string('city').primary();
    });
    
    await knex.schema.createTable('persons', table => {
        table.increments('id').primary();
        table.string('addressId').references('addresses.city');
        table.string('firstName');
    });
}

async function main() {
    const sylvester = await Person.query()
        .upsertGraphAndFetch({
            firstName: 'Sylvester',
            address: {
                city: 'Paris',
            },
        }, { insertMissing: ['address'] });
    
    console.log('Sylvester:', sylvester);
    
    const sylvesterLeftParis = await Person
        .query()
        .debug()
        .upsertGraphAndFetch({
            id: sylvester.id,
            firstName: 'Sylvester',
        });
        
    console.log('Sylvester left Paris:', sylvesterLeftParis);
    
    const addresses = await Address.query();
    
    console.log('addresses:', addresses);
    
    return Promise.resolve();
}

createSchema()
    .then(main)
    .catch(console.error);

Expected result :

Sylvester left Paris: Person { id: 1, addressId: null, firstName: 'Sylvester' }
Addresses: []

Actual result :

Sylvester left Paris: Person { id: 1, addressId: 'Paris', firstName: 'Sylvester' }
Addresses: [ Address { city: 'Paris' } ]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions