seegno / bookshelf-cascade-delete Goto Github PK
View Code? Open in Web Editor NEWCascade delete with Bookshelf.js
Home Page: http://seegno.github.io/bookshelf-cascade-delete
Cascade delete with Bookshelf.js
Home Page: http://seegno.github.io/bookshelf-cascade-delete
Installed the package. Seems like you require a devDependency.
I ran npm install inside the module to make it work for now.
There aren't any releases from august, but there are a few helpful commits, e.g. better postgres config support. Thank you.
PROBLEM:
Can't listen for any destroy events when cascade deleting.
USAGE EXAMPLE:
Delete an image from a gallery, where Gallery
is a collection of gallery images where each it's model is morphed into an universal/reused File
model that handles files connected with file-system.
Gallery model
module.exports = bookshelf.Model.extend({
tableName: 'item_gallery',
hasTimestamps: false,
image () { return this.morphOne('File', 'imageable'); }
}, {
dependents: ['image']
});
File model
module.exports = bookshelf.model('File', {
tableName: 'file',
hasTimestamps: false,
destroy () {
console.log('destroy');
return bookshelf.Model.prototype.destroy.apply(this, arguments);
},
initialize () {
this.on('destroying', () => console.log('destroying'));
this.on('destroyed', () => console.log('destroyed'));
}, {
};
EXPECTED:
Output any console.log.
ACTUAL:
When destroying none of the console.log get called.
NOTE:
Using built-in bookshelf plugin registry
for registering relationship models.
Wondering, why for the cascading destroying we can't just get the dependents
list and for each using model.related(
<item_from_dependents>).destroy()
or map over them incase of model to destroy them?
As shown on #8.
Ho there, I am using bookshelf with registry plugin and I have the following model:
var bookshelf = require('../bin/database');
var cascadeDelete = require('bookshelf-cascade-delete');
bookshelf.plugin(cascadeDelete);
bookshelf.plugin('registry');
var Client = bookshelf.Model.extend({
tableName: 'clients',
hasTimestamps: true,
users: function() {
return this.hasMany('User');
},
companies: function() {
return this.hasMany('ClientsCompany');
},
jobs: function() {
return this.hasMany('ClientsJob');
},
candidates: function() {
return this.hasMany('Lead');
}
}, {
dependents: ['users' ]
});
module.exports = bookshelf.model('Client', Client);
I am trying to use cascade-delete but it gives me an error:
TypeError: Cannot read property 'column' of undefined
at Child.cascadeDelete (C:\Projects\copy\frozen-crawl\node_modules\bookshelf-cascade-delete\dist\index.js:95:54)
I guess it doesn't like the string in hasMany(). I have a ton of models using the registry plugin and I'll appreciate a way to make this work without having to modify all of them...
Thanks in advance...
EDIT: here is the route:
router.delete('/:id', function(req, res, next) {
Client
.forge({ id: req.body.id })
.destroy()
.then((deleted) => {
res.status(201).json({
message: 'Client deleted'
})
})
.catch(err => {
console.log(err);
res.status(500).json({
title: 'An error has occured',
error: err
})
});
})
Hi, first of all, thank you for this plugin!! It's awesome! ๐ฅ
There's only one thing that I didn't find how to do and that is: when I destroy a model, if that model has manyToMany
relationships, how do I proceed? for instance:
const User = bookshelf.Model.extend({
tableName: 'users',
hasTimestamps: true,
addresses: function() {
return this.hasMany('Location', 'user_id');
},
services: function() {
return this.belongsToMany('Tag'); //n:m <--- this one right here
},
projects: function() {
return this.hasMany('Project', 'user_id');
},
reviews: function() {
return this.hasMany('Review', 'user_id');
}
},{
dependents:['addresses', 'services', 'projects', 'reviews']
});
there's a tags_users
table in my database used as a junction table, but whenever I try to destroy this model, I get the following error:
Unhandled rejection error: delete from "tags" where user_id IN ('5') - column "user_id" does not exist at Connection.parseE (/Users/cesar/dev/criarme/constroifacil/pinky/node_modules/pg/lib/connection.js:539:11) at Connection.parseMessage (/Users/cesar/dev/criarme/constroifacil/pinky/node_modules/pg/lib/connection.js:366:17) at Socket.<anonymous> (/Users/cesar/dev/criarme/constroifacil/pinky/node_modules/pg/lib/connection.js:105:22) at emitOne (events.js:77:13) at Socket.emit (events.js:169:7) at readableAddChunk (_stream_readable.js:146:16) at Socket.Readable.push (_stream_readable.js:110:10) at TCP.onread (net.js:529:20)
Any ideas? Thank you again! ( i'm not sure if this is the place to post such a doubt, but since I didn't find any better place, I just posted here :D )
hello, what if we have a self relation? I'm getting Maximum call stack size exceeded in the following model:
const Organisation = bookshelf.Model.extend({
tableName: 'organisations',
hasTimestamps: true,
users: function() {
return this.hasMany(User, 'OrganisationId');
},
clientOfOrganisation: function(){
return this.belongsTo(Organisation, 'clientOfOrganisationId')
},
organisations: function(){
return this.hasMany(Organisation, 'clientOfOrganisationId');
},
},{
dependents: ['users', 'organisations'],
byName: function(name, params = {}){
return this.forge().query({where:{ name: name }}).fetch(params);
}
})
I think that the error exists in the following block, where the dependency map is building:
dependencyMap(skipDependents = false) {
if (skipDependents || !this.dependents) {
return;
}
return reduce(this.dependents, (result, dependent) => {
const { relatedData } = this.prototype[dependent]();
const skipDependents = relatedData.type === 'belongsToMany';
return [
...result, {
dependents: relatedData.target.dependencyMap(skipDependents),
key: relatedData.key('foreignKey'),
model: relatedData.target,
skipDependents,
tableName: skipDependents ? relatedData.joinTable() : relatedData.target.prototype.tableName
}];
}, []);
},
P.S. Is there an ES6 class support?
The plugin throws an error:
Unhandled rejection TypeError: Cannot read property 'toString' of undefined
at Function.recursiveDeletes (/home/project/node_modules/bookshelf-cascade-delete/dist/index.js:91:113)
at cascadeDelete (/home/project/node_modules/bookshelf-cascade-delete/dist/index.js:42:54)
Probably because it doesn't account for non-default idAttribute values like 'post_id' instead of 'id'
i am trying to achieve something like this and can not find any documentation in this plugin to achieve it
basically i want to only delete specific items of the parent model without deleting the model
ParentModel.fetch({withRelated: ['items]]}).find({itemId: 200}).destroy()
The next code throws error:
new User().where({ username: 'some username' }).destroy();
This happens because of the code in the 'recursiveDeletes' function:
var parentValue = typeof parent === 'number' || typeof parent === 'string' ? '\'' + parent + '\'' : parent.toString();
Because there is no id so the parent
is undefined...
I'm trying to delete all objects in the list, but only the support table and the news table itself are deleted
bookshelf.model('News', {
tableName: 'news',
files(){
return this.belongsToMany('Files').through('NewsFiles');
},
}, {
dependents: ['files']
});
delete:
await models.news.where({ id }).destroy({ cascadeDelete: true });
the files entry is not destroyed.
I'm not sure what exactly triggered this in one particular modal. I am also using bookshelf-paranoia
which also overrides destroy
.
I was able to fix it for my case by replacing this._knex
by this.eloquent.knex
in line 70.
- const id = this.get(this.idAttribute) || this._knex.column(this.idAttribute);
+ const id = this.get(this.idAttribute) || this.eloquent.knex.column(this.idAttribute);
It seems like the constructed delete queries only match the IDs, while with morph relations you'd have to check both the ID & type columns. This leads to unwanted deletes.
I realized that the hard way, maybe it would be worth documenting this limitation and/or skipping the data (like you seem to do with belongsToMany
) until this type of relation is supported.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.