0

I've got an issue with a nested property that uses a composite key.

When I'm editing a model that has multiple instances of nested properties (with a composite key) and want to update it to have fewer by leaving them blank, cfWheels does not remove the ones that are not used anymore, and maintains the old value. Is there a way of forcing the deletion of these without calling delete on the nested model?

I've been doing by deleting all nested properties, and then update() creates the records that are needed, but the big issue with that is that when I have code in between that fails, It just deletes the items, which as you know can be very very bad.

Daniel
  • 34,125
  • 17
  • 102
  • 150
  • also if I run an update, and the key combination already exists, it gives me a `Cannot insert duplicate key` Error – Daniel May 01 '13 at 22:10

2 Answers2

1

i think you forgot to mention allowDelete attribute in nestedProperties by defalut allowDelete is set as false in wheels and does not delete the composite key form table. you have to set it true. for example in model you have to do some thing like this.

   <cfset hasMany(name="campaignlanguages",shortcut="languages", dependent="deleteAll") />
   <cfsetnestedProperties(associations="campaignlanguages",allowDelete="true")/>

you can find more details here

Keshav jha
  • 1,356
  • 8
  • 22
1

In your init call to nestedProperties(), try adding the allowDelete option:

nestedProperties(association="comments", allowDelete=true);

Then if a model within that collection has a property called _delete that is set to true, CFWheels will delete that record.

I'm not sure of your model because you don't include any details in your question, but you could probably run a beforeValidationOnUpdate callback that checks criteria on the nested models and sets _delete = true when the record needs to be deleted.

For example:

// Post.cfc
component extends="Model" {
  function init() {
    hasMany("comments");
    nestedProperties(association="comments", allowDelete=true);
    beforeValidationOnUpdate("removeBlankComments");
  }

  private function removeBlankComments() {
    if (StructKeyExists(this, "comments") && IsArray(this.comments)) {
      for (local.i = 1; local.i < ArrayLen(this.comments); local.i++) {
        if (!Len(this.comments[local.i].message)) {
          this.comments[local.i]._delete = true;
        }
      }
    }
  }
}

Not sure if this will give you any problems with the nested composite key. Sometimes nested properties are a little kludgy with "special" cases.

Chris Peters
  • 17,918
  • 6
  • 49
  • 65
  • I've had the model set up that way already, I didn't have the `_delete` column in the table, which I've added, but it didn't change the behaviour. I'm going to try the hook and see if that works. I'm concerned though that if I use the `_delete` column, it may hide the nested property, but will not solve the issue where the PRIMARY KEY constraint is violated. `Cannot insert duplicate key in object` – Daniel May 02 '13 at 14:50
  • How does the model(as I'm updating it), know which nested properties to remove? – Daniel May 02 '13 at 15:11
  • `_delete` is a "virtual" property, so you don't need a matching column in the table. When you update the parent object, it should go through the children and run a deletion on any children that are marked for deletion with that property. – Chris Peters May 02 '13 at 16:05