[FIX] mail: insert data in relational field
Before this commit, when a record was identified by relational fields, we couldn't insert this record by passing data rather than the records. We should be able to insert records and data in the models, so passing data should be ok. This commit fixes this issue by backporting some code of improvements and fixes from master. Note that the internal code of model is written for retrocompatibility, so some added features like store.Model in diff is ok. Part-of: odoo/odoo#144999
This commit is contained in:
@@ -28,6 +28,7 @@ export function OR(...args) {
|
||||
}
|
||||
|
||||
export function makeStore(env) {
|
||||
let storeReady = false;
|
||||
const res = {
|
||||
// fake store for now, until it becomes a model
|
||||
/** @type {import("models").Store} */
|
||||
@@ -115,7 +116,16 @@ export function makeStore(env) {
|
||||
/** @param {Record} receiver */
|
||||
set(target, name, val, receiver) {
|
||||
return Record.MAKE_UPDATE(() => {
|
||||
if (name === "Model" || !(name in target.Model._fields)) {
|
||||
if (name === "Model") {
|
||||
Reflect.set(target, name, val, receiver);
|
||||
return true;
|
||||
}
|
||||
if (target instanceof BaseStore && storeReady && name in Models) {
|
||||
// "store.Model =" is considered a Model.insert()
|
||||
res.store[name].insert(val);
|
||||
return true;
|
||||
}
|
||||
if (!(name in target.Model._fields)) {
|
||||
Reflect.set(target, name, val, receiver);
|
||||
return true;
|
||||
}
|
||||
@@ -388,6 +398,7 @@ export function makeStore(env) {
|
||||
Model.store = res.store;
|
||||
res.store[Model.name] = Model;
|
||||
}
|
||||
storeReady = true;
|
||||
return res.store;
|
||||
}
|
||||
|
||||
@@ -1311,8 +1322,20 @@ export class Record {
|
||||
const obj = new this.Class();
|
||||
obj.Model = this;
|
||||
const ids = this._retrieveIdFromData(data);
|
||||
for (const name in ids) {
|
||||
if (
|
||||
ids[name] &&
|
||||
!Record.isRecord(ids[name]) &&
|
||||
!Record.isCommand(ids[name]) &&
|
||||
Record.isRelation(this._fields[name])
|
||||
) {
|
||||
// preinsert that record in relational field,
|
||||
// as it is required to make current local id
|
||||
ids[name] = this.store[this._fields[name].targetModel].preinsert(ids[name]);
|
||||
}
|
||||
}
|
||||
let record = Object.assign(obj, {
|
||||
localId: this.localId(data),
|
||||
localId: this.localId(ids),
|
||||
...ids,
|
||||
});
|
||||
Object.assign(record, { _store: this.store });
|
||||
|
||||
@@ -278,3 +278,25 @@ QUnit.test("onAdd hook should see fully inserted data", async (assert) => {
|
||||
thread.members.add({ name: "John", type: "admin" });
|
||||
assert.verifySteps(["Thread.onAdd::John.admin"]);
|
||||
});
|
||||
|
||||
QUnit.test("Can insert with relation as id, using relation as data object", async (assert) => {
|
||||
(class User extends Record {
|
||||
static id = "name";
|
||||
name;
|
||||
settings = Record.one("Settings");
|
||||
}).register();
|
||||
(class Settings extends Record {
|
||||
static id = "user";
|
||||
pushNotif;
|
||||
user = Record.one("User", { inverse: "settings" });
|
||||
}).register();
|
||||
const store = await start();
|
||||
store.Settings.insert([
|
||||
{ pushNotif: true, user: { name: "John" } },
|
||||
{ pushNotif: false, user: { name: "Paul" } },
|
||||
]);
|
||||
assert.ok(store.User.get("John"));
|
||||
assert.ok(store.User.get("John").settings.pushNotif);
|
||||
assert.ok(store.User.get("Paul"));
|
||||
assert.notOk(store.User.get("Paul").settings.pushNotif);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user