diff --git a/addons/mail/static/src/core/common/record.js b/addons/mail/static/src/core/common/record.js index f0e9948f65c..e29f14499b2 100644 --- a/addons/mail/static/src/core/common/record.js +++ b/addons/mail/static/src/core/common/record.js @@ -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 }); diff --git a/addons/mail/static/tests/core/record_tests.js b/addons/mail/static/tests/core/record_tests.js index 20cc42cff30..c8e3d09c6b1 100644 --- a/addons/mail/static/tests/core/record_tests.js +++ b/addons/mail/static/tests/core/record_tests.js @@ -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); +});