Skip to content

Add support for many nested objects in SaveOperations #1104

@jwoertink

Description

@jwoertink

Original Issue: #43

I'm writing a new issue because the original one was created a long time ago and makes mention of a lot of things that no longer exist, though the sentiment is still the same.

We need a way to support creating and updating many nested records for a parent object.

Given a JSON payload that looks like this:

{
  "menu": {
    "title": "Main Menu",
    "active": true,
  }
  "items": [
    {
      "title": "First item",
      "active": true,
      "position": 0
    },
    {
      "title": "Second item",
      "active": false,
      "position": 1
    }
  ]
}

I should be able to use these params to create a new menu object as well as 2 new item objects. This must be able to support the ability to decide which of the nested keys are permitted and which are not similar to using permit_columns which helps to prevent updating unpermitted columns.

This is a rough idea of the intent:

class SaveMenu < Menu::SaveOperation
  permit_columns title, active

  has_many items : SaveItem
end

class SaveItem < Item::SaveOperation
  permit_columns title, active, position
end

# `params` here represents the above json structure
SaveMenu.create!(params)

Under the hood, we can use params.many_nested(:items) here. Ideally this should also update them in a single query. Each nested record could run through the operation to check all validations and run any data transformations that need to happen, then once all operations are valid? and have no errors, then it submits the single query.

Last thing to consider is if an Item requires a menu_id, then the items can't even begin to save until the menu has already been saved and created. This whole thing will need to be inside of a transaction so if the items fail to save, the transaction can be rolledback to remove the menu.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions