dexie / Dexie.js

A Minimalistic Wrapper for IndexedDB
https://dexie.org
Apache License 2.0
11.65k stars 641 forks source link

How to protect record from storing it's "join" property? #880

Open s0thl opened 5 years ago

s0thl commented 5 years ago

Hi,

I'm joining the account comments from the other table like so:

interface IAccountDataModel {
  id?: number;
  username: string;
  uniqueId: string;
  created?: number;
  comments?: ICommentsDataModel[];
}

public accounts!: Dexie.Table<IAccountDataModel, number>;
public comments!: Dexie.Table<ICommentsDataModel, number>;

db.version(1).stores({
    accounts: "++id,username,uniqueId,created",
    comments: "++id,message,accountId"
});

public async getAccount(options: { [key: string]: any } & Partial<IAccountDataModel>): Promise<IAccountDataModel | undefined> {
    return await this.accounts.get(options, async account => {
      if (account) {
        account.comments = await this.comments.where({ 'accountId': account.id }).toArray();
        return account;
      }
      return undefined;
    });
}

So comments are now attached the account instance, that's fine.

The problem appears, when that account instance is actually saved into the data store.

Consider following:

// Query account
let account = getAccount({'username' : 'DexieIsC00l'});

// Following line is expected to do nothing, as no field was changed and record already exist
db.accounts.put(account);

As said in the (code) comment, account shouldn't be altered, since nothing was changed (excluding the 'join').

Instead, the joined comments are actually saved along with the account into the accounts table!

https://i.imgur.com/7QozsfH.png image

Why does that happen? I do have some MySQL/SQLite background and to me, it looks weird and wasteful.

What would be a workaround for this? delete account.comments; before each put call? Make it look unreasonable and it's kinda pointless, speaking of joining principles.

dfahlander commented 5 years ago

The dexie-relationships add-on solves this by attaching relation properties as non-enumerable .

s0thl commented 5 years ago

Why wont you implement such a base thing into the Dexie core? I'm worried that addon is created by other developer, hence no updates & compatibility with current version of Dexie is guaranteed. 🤔

s0thl commented 5 years ago

Side question; is there an advanced project using Dexie I could lookup for a structure and good practices in general? Thanks for your replies. Much appreciated.

dfahlander commented 5 years ago

I don't want to include too much in Dexie - not to bloat it with code that not everyone use. Dexie relationships is maintained by me and other dev. An integration test is included in dexie's CI that makes sure keeping operability with dexie-relationships.

There are lots of advanced projects using dexie both closed and open source. I'm not keeping track of them but I've tried to list some of them here