[PR #262] [MERGED] Render a schedule rule with the mapped payee id; fixes crash #3083

Closed
opened 2026-02-28 20:36:03 -06:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/actualbudget/actual/pull/262
Author: @jlongster
Created: 10/4/2022
Status: Merged
Merged: 10/6/2022
Merged by: @jlongster

Base: masterHead: schedule-value-render-fix


📝 Commits (1)

  • 2ee0520 Render a schedule rule with the mapped payee id; fixes crash

📊 Changes

1 file changed (+3 additions, -3 deletions)

View changed files

📝 packages/desktop-client/src/components/modals/ManageRules.js (+3 -3)

📄 Description

This bug has been around for a while and I finally tracked it down. The fix is small, but requires understanding several important things:

  • When an item is deleted, several other items may be pointing to it. In several cases, we allow changing this pointer. One case is when you merge payees; we delete all but 1 payee, and change the pointers of all of the deleted ones to the final one. Everything else in the system that uses payees will automatically be linked to the final payee (if any of the merged payees was used)
  • To do this, we have "mappings" tables with two columns: one id of the real item, and a second id of the item it "points" to. When querying for items, we always need to join through this table. This is only needed for categories and payees (I think?), and it's automatically handled internally for most queries.
  • We can't always do this mapping easily in SQL though. One case is rules; the actions and conditions are stored as JSON blobs. This JSON can contain ids that need mapping; unfortunately, we have to resort to doing the mapping for rule actions and conditions in JS. That means the JSON blob always stores unmapped ids
  • Schedules do have special fields, however. When the query system returns them, they contain _payee, _account, _amount, and _date. These are all still constructed in a single SQL statement; it uses json_extract to pull these conditions out because we need them so much for working with schedules. Most importantly: it maps the ids for these fields! This removes most of the burden

(These fields have underscores to mark that they aren't real fields, and if an object is submitted as a mutation it'll automatically strip those fields away)

When reading values like payee from a schedule, you shouldn't touch _conditions directly because you can run into problems. Here, we were using the unmapped payee id so when it tries to render it, that payee doesn't exist (since it's been deleted). We need to use the mapped version, which is simple because the query system has already gotten it for us.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/actualbudget/actual/pull/262 **Author:** [@jlongster](https://github.com/jlongster) **Created:** 10/4/2022 **Status:** ✅ Merged **Merged:** 10/6/2022 **Merged by:** [@jlongster](https://github.com/jlongster) **Base:** `master` ← **Head:** `schedule-value-render-fix` --- ### 📝 Commits (1) - [`2ee0520`](https://github.com/actualbudget/actual/commit/2ee0520f6dfa7565790318c190b1580a255adf74) Render a schedule rule with the mapped payee id; fixes crash ### 📊 Changes **1 file changed** (+3 additions, -3 deletions) <details> <summary>View changed files</summary> 📝 `packages/desktop-client/src/components/modals/ManageRules.js` (+3 -3) </details> ### 📄 Description This bug has been around for a while and I finally tracked it down. The fix is small, but requires understanding several important things: * When an item is deleted, several other items may be pointing to it. In several cases, we allow changing this pointer. One case is when you merge payees; we delete all but 1 payee, and change the pointers of all of the deleted ones to the final one. Everything else in the system that uses payees will automatically be linked to the final payee (if any of the merged payees was used) * To do this, we have "mappings" tables with two columns: one id of the real item, and a second id of the item it "points" to. When querying for items, we _always_ need to join through this table. This is only needed for categories and payees (I think?), and it's automatically handled internally for most queries. * We can't always do this mapping easily in SQL though. One case is rules; the actions and conditions are stored as JSON blobs. This JSON can contain ids that need mapping; unfortunately, we have to resort to doing the mapping for rule actions and conditions in JS. That means the JSON blob always stores unmapped ids * Schedules do have special fields, however. When the query system returns them, they contain `_payee`, `_account`, `_amount`, and `_date`. These are all still constructed in a single SQL statement; it uses `json_extract` to pull these conditions out because we need them so much for working with schedules. Most importantly: it maps the ids for these fields! This removes most of the burden (These fields have underscores to mark that they aren't real fields, and if an object is submitted as a mutation it'll automatically strip those fields away) When reading values like `payee` from a schedule, you shouldn't touch `_conditions` directly because you can run into problems. Here, we were using the unmapped payee id so when it tries to render it, that payee doesn't exist (since it's been deleted). We need to use the mapped version, which is simple because the query system has already gotten it for us. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-02-28 20:36:03 -06:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#3083