addon/utils/pathify.js
function pathifyModel (model, store, prefix) {
  let result = []
  if (prefix) result.push(prefix)

  if (get(model, '_internalModel.modelName') === 'uni-form') {
    const propPath = propertyPath('payload', prefix)
    if (model.get('payload') instanceof DS.Model) {
      return result.concat(pathifyModel(model.get('payload'), store, propPath))
    }
    return result.concat(pathifyObject(model.get('payload'), store, propPath))
  }

  // Pathify serializer output
  const payload = model.serialize()
  const { attributes, data } = payload

  if (attributes) result = result.concat(pathifyObject(attributes, store, prefix)) // JSONAPI
  else if (data) result = result.concat(pathifyObject(data, store, prefix)) // JSONAPI
  else result = result.concat(pathifyObject(payload, store, prefix)) // Not JSONAPI

  // Pathify model attributes and child models which will be serialized
  const serializer = store.serializerFor(get(model, '_internalModel.modelName'))

  model.eachAttribute(name => result.push(propertyPath(name, prefix)))
  model.eachRelationship((name, { kind, type }) => {
    if (kind === 'hasMany') return // not supported
    const childPath = propertyPath(name, prefix)
    const willSerialize = get(serializer, `attrs.${name}.serialize`) === 'records' ||
      get(serializer, `attrs.${name}.embedded`) === 'always'
    if (!willSerialize) {
      result.push(childPath)
    } else {
      const instance = store.createRecord(type)
      result = result.concat(pathifyModel(instance, store, childPath))
      store.deleteRecord(instance)
    }
  })

  return result.uniq()
}
function pathifyModel (model, store, prefix) {
  let result = []
  if (prefix) result.push(prefix)

  if (get(model, '_internalModel.modelName') === 'uni-form') {
    const propPath = propertyPath('payload', prefix)
    if (model.get('payload') instanceof DS.Model) {
      return result.concat(pathifyModel(model.get('payload'), store, propPath))
    }
    return result.concat(pathifyObject(model.get('payload'), store, propPath))
  }

  // Pathify serializer output
  const payload = model.serialize()
  const { attributes, data } = payload

  if (attributes) result = result.concat(pathifyObject(attributes, store, prefix)) // JSONAPI
  else if (data) result = result.concat(pathifyObject(data, store, prefix)) // JSONAPI
  else result = result.concat(pathifyObject(payload, store, prefix)) // Not JSONAPI

  // Pathify model attributes and child models which will be serialized
  const serializer = store.serializerFor(get(model, '_internalModel.modelName'))

  model.eachAttribute(name => result.push(propertyPath(name, prefix)))
  model.eachRelationship((name, { kind, type }) => {
    if (kind === 'hasMany') return // not supported
    const childPath = propertyPath(name, prefix)
    const willSerialize = get(serializer, `attrs.${name}.serialize`) === 'records' ||
      get(serializer, `attrs.${name}.embedded`) === 'always'
    if (!willSerialize) {
      result.push(childPath)
    } else {
      const instance = store.createRecord(type)
      result = result.concat(pathifyModel(instance, store, childPath))
      store.deleteRecord(instance)
    }
  })

  return result.uniq()
}
function pathifyModel ( model , store , prefix ) { let result = [ ] if ( prefix ) result . push ( prefix ) if ( get ( model , '_internalModel.modelName' ) === 'uni-form' ) { const propPath = propertyPath ( 'payload' , prefix ) if ( model . get ( 'payload' ) instanceof DS . Model ) { return result . concat ( pathifyModel ( model . get ( 'payload' ) , store , propPath ) ) } return result . concat ( pathifyObject ( model . get ( 'payload' ) , store , propPath ) ) } // Pathify serializer output const payload = model . serialize ( ) const { attributes , data } = payload if ( attributes ) result = result . concat ( pathifyObject ( attributes , store , prefix ) ) // JSONAPI else if ( data ) result = result . concat ( pathifyObject ( data , store , prefix ) ) // JSONAPI else result = result . concat ( pathifyObject ( payload , store , prefix ) ) // Not JSONAPI // Pathify model attributes and child models which will be serialized const serializer = store . serializerFor ( get ( model , '_internalModel.modelName' ) ) model . eachAttribute ( name => result . push ( propertyPath ( name , prefix ) ) ) model . eachRelationship ( ( name , { kind , type } ) => { if ( kind === 'hasMany' ) return // not supported const childPath = propertyPath ( name , prefix ) const willSerialize = get ( serializer , ` ${ name } ` ) === 'records' || get ( serializer , ` ${ name } ` ) === 'always' if ( ! willSerialize ) { result . push ( childPath ) } else { const instance = store . createRecord ( type ) result = result . concat ( pathifyModel ( instance , store , childPath ) ) store . deleteRecord ( instance ) } } ) return result . uniq ( ) }
Belt-and-suspenders approach gets field paths from both the ultimate payload and the model data structure in memory.
Belt - and - suspenders approach gets field paths from both the ultimate payload and the model data structure in memory .