impr: 🚸 Sostituito relationship con setter custom

This commit is contained in:
Maicol Battistini 2022-01-03 15:11:32 +01:00
parent 255a198ab5
commit bc76c3c833
No known key found for this signature in database
GPG Key ID: 4FDB0F87CDB1D34A
2 changed files with 18 additions and 68 deletions

View File

@ -14,6 +14,7 @@ import type {
TextFieldT
} from '../../types';
import {
getFormData,
isFormValid,
showSnackbar
} from '../../utils';
@ -63,6 +64,8 @@ export class RecordsPage extends Page {
model: typeof Model;
customSetter: (model: Model, fields: Cash) => void;
/**
* What fields should take precedence when saving the record
*/
@ -290,15 +293,19 @@ export class RecordsPage extends Page {
// eslint-disable-next-line new-cap
const instance: Model = new this.model();
const fields = form.find('text-field, text-area, material-select');
for (const fieldName of this.fieldsPrecedence) {
const field = fields.find(`#${fieldName}`);
instance[field.attr('id')] = field.val();
}
if (this.customSetter) {
this.customSetter(instance, getFormData(form));
} else {
const fields = form.find('text-field, text-area, material-select');
fields.filter(this.fieldsPrecedence.map(value => `#${value}`).join(', '))
.each((index, field) => {
instance[field.id] = field.value;
});
fields.each((index, field: TextField | TextArea) => {
instance[field.id] = field.value;
});
fields.each((index, field: TextField | TextArea) => {
instance[field.id] = field.value;
});
}
const response = await instance.save();
if (response.getModelId()) {

View File

@ -1,12 +1,8 @@
import {collect} from 'collect.js';
import {
type PluralResponse,
Model as BaseModel
} from 'coloquent';
import {
capitalize,
snakeCase
} from 'lodash-es';
import {snakeCase} from 'lodash-es';
// noinspection JSPotentiallyInvalidConstructorUsage
/**
@ -18,44 +14,13 @@ import {
export default class Model extends BaseModel {
jsonApiType: string;
/**
* Specifies the list of relationships, with their model(s) and getters/setters
*
* @type {{[p: string]: {model: typeof Model, get, set}}}
*/
relationValues: {[string]: {
model: typeof Model | (typeof Model)[],
get: {[string]: (models: Model | Model[]) => any},
set: {[string]: (models: Model | Model[]) => void},
}} = {}
/**
* Specifies the list of attributes that should be obtained from the model relation
* @type {{[p: string]: string}}
* @private
*/
#relationAttributesGet: {[string]: string} = {};
/**
* Specifies the list of attributes that should be set in the model relation
* @type {{[p: string]: string}}
* @private
*/
#relationAttributesSet: {[string]: string} = {};
constructor() {
super();
const collection = collect(this.relationValues);
this.#relationAttributesGet = collection.pluck('get').keys().all();
this.#relationAttributesSet = collection.pluck('set').keys().all();
// Return a proxy of this object to allow dynamic attributes getters and setters
// eslint-disable-next-line no-constructor-return
return new Proxy(this, {
get(target: this, property, receiver) {
if (property in target.#relationAttributesGet) {
return target.relationValue(property);
}
const snakeCasedProperty = snakeCase(property);
if (snakeCasedProperty in target.getAttributes()) {
return target.getAttribute(snakeCasedProperty);
@ -64,11 +29,8 @@ export default class Model extends BaseModel {
return Reflect.get(target, property, receiver);
},
set(target: this, property, value, receiver) {
if (property in target.#relationAttributesSet) {
return target.relationValue(property, 'set', value);
}
return target.setAttribute(snakeCase(property), value);;
target.setAttribute(snakeCase(property), value);
return true;
}
});
}
@ -107,23 +69,4 @@ export default class Model extends BaseModel {
getJsonApiType(): string {
return (super.getJsonApiType() ?? snakeCase(this.constructor.name));
}
/**
* Returns the attribute of the specified relationship.
*/
// eslint-disable-next-line default-param-last
relationValue(attribute: string, action: 'get' | 'set' = 'get', value: any): void | any {
const relation = this[`relationAttributes${capitalize(action)}`][attribute];
const callback = this.relationValues[relation][action][attribute];
let istanza = this.getRelation(relation);
const model = this.relationValues[relation].model
if (!istanza && !Array.isArray(model)) {
// eslint-disable-next-line new-cap
istanza = new model();
this.setRelation(relation, istanza);
}
return callback(istanza, value);
}
}