Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Deletion Rules for Relationships? #540

Open
konstantinbe opened this Issue Jul 5, 2011 · 5 comments

Comments

Projects
None yet
6 participants
Contributor

konstantinbe commented Jul 5, 2011

Lets say we have a Book record with a to-many relationship pages to Page records with an inverse relationship book. Now:

  • When deleting a page, it should be removed from the book referencing it
  • When deleting a book, all contained pages should also be deleted

Core Data allows one to specify deletion rules as described here:

http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdRelationships.html#//apple_ref/doc/uid/TP40001857-SW1

I'd assume at least nullify to be implemented by default, but it seems not to be the case as shown in the example below, maybe I'm doing something wrong?

Questions:

  1. Is it possible to specify deletion rules in SproutCore?
  2. If yes, how?
  3. If not, best practices?

Example

/*globals Book Page */

// define books
Book = SC.Record.extend({
    pages: SC.Record.toMany('Page', {
        inverse: 'book',
        isMaster: YES
    })
});

// define pages
Page = SC.Record.extend({
    book: SC.Record.toOne('Book', {
        inverse: 'pages',
        isMaster: NO
    })
});

// don't forget to set the record type names
Book.recordTypeName = 'Book';
Page.recordTypeName = 'Page';

// create the store
var store = SC.Store.create();

// create a book and a page
var book = store.createRecord(Book, {guid: "book-1"});
var page = store.createRecord(Page, {guid: "page-1"});

// add the page to the book
book.get('pages').pushObject(page);

// ok, book references the page
console.log(book.get('pages').mapProperty('guid'));

// ok, page references the book
console.log(page.get('book').get('guid'));

// now destroy the page
page.destroy();

// ok, page is destroyed
console.log(page.get('isDestroyed'));

// error, book still references the page
console.log(book.get('pages').mapProperty('guid'));

Here is also a version with SC.RunLoop calls:

https://gist.github.com/1065451

CRIZN commented Jul 20, 2011

This is actually an issue that I recently ran into. It's basically makes binding these relationship objects to views pointless. Which could otherwise be super valuable.

Contributor

erichocean commented Jul 20, 2011

That works for child records ({ nested: true }) AFAIK, but not in the case that you describe. You can override destroy() to implement the behavior you've mentioned (and probably in a generic way, that loops over the relationships, checks the deletion behavior, and Does the Right Thing™.

Contributor

erichocean commented Jul 20, 2011

And for what it's worth, even though Core Data does have the defaults, I've found that the vast majority of my Core Data apps have to implement manual deletion behavior anyway. YMMV.

CRIZN commented Jul 20, 2011

Cool thanks for the advice. We were just planning on doing the same thing you described for both create and destroy. Guess it's time to get coding!

Thanks again,

Chris

Owner

dcporter commented Nov 24, 2013

Having a useful onDelete parameter on toOne and toMany would be a great feature. Would it be okay to only support it when both sides of a relationship are defined? (I assume yes.) This prevents us from doing bananas things like observing isDestroyed on every related record. I would support the default becoming NULLIFY from the current DO_NOTHING_USELESSLY. (In an ideal world, the ability to retain relationships with destroyed records would go away entirely, right?)

I know this is an old ticket, but does anyone have anything that could be put into a pull request?

@publickeating publickeating modified the milestone: 1.12.0, 1.11.0 Dec 3, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment