Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

fix(core): prevent timestamp stripping in Model.build (#7284)#18173

Open
abdelrahmanSheref101 wants to merge 3 commits into
sequelize:mainsequelize/sequelize:mainfrom
abdelrahmanSheref101:fix/core-7284-build-timestampsabdelrahmanSheref101/sequelize:fix/core-7284-build-timestampsCopy head branch name to clipboard
Open

fix(core): prevent timestamp stripping in Model.build (#7284)#18173
abdelrahmanSheref101 wants to merge 3 commits into
sequelize:mainsequelize/sequelize:mainfrom
abdelrahmanSheref101:fix/core-7284-build-timestampsabdelrahmanSheref101/sequelize:fix/core-7284-build-timestampsCopy head branch name to clipboard

Conversation

@abdelrahmanSheref101
Copy link
Copy Markdown

@abdelrahmanSheref101 abdelrahmanSheref101 commented Mar 28, 2026

Pull Request Checklist

  • Have you added new tests to prevent regressions?
  • If a documentation update is necessary, have you opened a PR to the documentation repository?
  • Did you update the typescript typings accordingly (if applicable)?
  • Does the description below contain a link to an existing issue (Closes Model.build strips off timestamps #7284) or a description of the issue you are solving?
  • Does the name of your PR follow our conventions?

Description of Changes

This PR resolves an issue where Model.build() would strip createdAt and updatedAt values when an instance was rebuilt from a JSON object (e.g., Model.build(instance.toJSON())).

  • Logic Fix: Modified _initValues to ensure timestamps are assigned when isNewRecord is false. This allows the model to correctly hydrate existing data that includes manual timestamp values.
  • Testing: Added a unit test in test/unit/instance/build.test.js to verify that timestamps are retained during a round-trip build.

List of Breaking Changes

None. This fix aligns the behavior of Model.build with standard attribute hydration for existing records.

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of read-only attributes during model instance construction, ensuring they are properly preserved when building existing instances.

- Fixes issue where Model.build(instance.toJSON()) stripped timestamps.
- Ensure timestamps are assigned in _initValues when isNewRecord is false.
- Added unit test in build.test.js for round-trip consistency.
@abdelrahmanSheref101 abdelrahmanSheref101 requested a review from a team as a code owner March 28, 2026 10:10
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 28, 2026

📝 Walkthrough

Walkthrough

The changes fix an issue where Model.build() loses read-only attribute values (such as manually-defined timestamps) when reconstructing instances from serialized JSON. The fix updates the _initValues method to handle read-only attributes specially during non-new instance construction, and adds a test validating the fix.

Changes

Cohort / File(s) Summary
Core Model Logic
packages/core/src/model.js
Updated _initValues to iterate over readOnlyAttributeNames and set each attribute from incoming values with raw: true flag before processing remaining values, preserving read-only fields during instance reconstruction.
Test Coverage
packages/core/test/unit/instance/build.test.js
Added comprehensive unit test validating that manually-defined timestamp attributes (createdAt, updatedAt) survive the serialization/deserialization cycle via Model.build(instance.toJSON()).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A timestamp's journey through JSON's embrace,
Lost in the rebuild, time falls from its place,
But now with raw magic, the dates find their way,
Back into dataValues, preserved and to stay! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR directly addresses issue #7284 by updating _initValues to handle read-only/manual timestamp attributes when constructing existing instances, preserving timestamps through Model.build(instance.toJSON()) round-trips.
Out of Scope Changes check ✅ Passed All changes are in-scope: the core fix modifies _initValues to handle read-only attributes for existing records, and the test validates the specific issue of timestamp preservation during rebuild operations.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The PR title accurately summarizes the main change: preventing timestamp stripping in Model.build, which matches the core fix in _initValues for handling read-only/timestamp attributes when constructing existing instances.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/core/test/unit/instance/build.test.js (1)

99-132: Test doesn't exercise the fix in _initValues.

This test uses timestamps: false with manually defined timestamp fields. With this configuration, createdAt/updatedAt are not in readOnlyAttributeNames, so the new code at lines 268-280 in model.js isn't triggered.

The fix addresses the case where:

  1. Timestamps are enabled (the default) — so createdAt/updatedAt are in readOnlyAttributeNames
  2. isNewRecord: false is passed to build() — triggering the new code path

Consider adding a test that verifies the actual fix:

💡 Suggested additional test
+    it('should retain timestamps when rebuilding with isNewRecord: false', () => {
+      const User = current.define('User', {
+        username: DataTypes.STRING,
+      }); // timestamps: true by default
+
+      const now = new Date();
+      now.setMilliseconds(0);
+
+      const instance = User.build(
+        {
+          username: 'user-name',
+          createdAt: now,
+          updatedAt: now,
+        },
+        { isNewRecord: false },
+      );
+
+      const json = instance.toJSON();
+      const rebuiltInstance = User.build(json, { isNewRecord: false });
+
+      expect(rebuiltInstance.get('createdAt')).to.be.an.instanceof(Date);
+      expect(rebuiltInstance.get('updatedAt')).to.be.an.instanceof(Date);
+      expect(rebuiltInstance.get('createdAt').getTime()).to.equal(now.getTime());
+      expect(rebuiltInstance.get('updatedAt').getTime()).to.equal(now.getTime());
+    });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/test/unit/instance/build.test.js` around lines 99 - 132, Add a
new unit test in build.test.js that exercises the _initValues code path by using
a model with default timestamps (do not set timestamps:false), defining
createdAt and updatedAt attributes, building an instance with isNewRecord: false
and providing createdAt/updatedAt values (use a Date with milliseconds zeroed),
then assert the rebuilt instance preserves those dates (instances of Date, equal
getTime()) and that dataValues contains createdAt/updatedAt; this ensures the
branch that checks readOnlyAttributeNames (the new logic in _initValues) is
actually tested when timestamps are enabled and build() is called with
isNewRecord:false.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/core/test/unit/instance/build.test.js`:
- Around line 99-132: Add a new unit test in build.test.js that exercises the
_initValues code path by using a model with default timestamps (do not set
timestamps:false), defining createdAt and updatedAt attributes, building an
instance with isNewRecord: false and providing createdAt/updatedAt values (use a
Date with milliseconds zeroed), then assert the rebuilt instance preserves those
dates (instances of Date, equal getTime()) and that dataValues contains
createdAt/updatedAt; this ensures the branch that checks readOnlyAttributeNames
(the new logic in _initValues) is actually tested when timestamps are enabled
and build() is called with isNewRecord:false.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b903e261-36fa-496a-b757-639ff7f68290

📥 Commits

Reviewing files that changed from the base of the PR and between df4a631 and 4dd9547.

📒 Files selected for processing (2)
  • packages/core/src/model.js
  • packages/core/test/unit/instance/build.test.js

@abdelrahmanSheref101 abdelrahmanSheref101 changed the title fix(core): preserve manual timestamps in _initValues (#7284) fix(core): prevent timestamp stripping in Model.build and enforce read-only guards (#7284) Mar 28, 2026
@abdelrahmanSheref101 abdelrahmanSheref101 changed the title fix(core): prevent timestamp stripping in Model.build and enforce read-only guards (#7284) fix(core): prevent timestamp stripping in Model.build (#7284) Mar 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Model.build strips off timestamps

1 participant

Morty Proxy This is a proxified and sanitized view of the page, visit original site.