متوقع:
عند إنشاء العمود updated_ts
في table.timestamps()
، يجب أن يكون DDL الخاص به:
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
فعلي:
جزء ON UPDATE CURRENT_TIMESTAMP
مفقود - العمود updated_ts
لا يتم تحديثه تلقائيًا.
بناء الجملة الذي أصفه يعمل مع MySQL ، ولست متأكدًا من مدى توافقه عبر محركات قواعد البيانات.
على الأقل مع بناء جملة postgres ليس هذا لطيفًا تمامًا:
http://stackoverflow.com/questions/1035980/update-timestamp-when-row-is-updated-in-postgresql
على الرغم من أنني أود أن يكون .autoUpdate()
باني طريقة ل timestamp
العمود، ثم سيكون تافها لتمكين هذا ل .timestamps()
المساعد للغاية.
يبدو أن SQLite3 يحتوي أيضًا على مشغلات يمكن استخدامها لتنفيذ ذلك. قد يكون لدى Oracle و mssql أيضًا بعض البنية اللغوية المناسبة لها أو على الأقل يمكن إجراؤها باستخدام المشغلات.
سيكون هذا لطيفا جدا! نحتاج حاليًا إلى الاعتماد على رف الكتب في تحديث الطوابع الزمنية لدينا ، أليس كذلك؟
بدلاً من الاعتماد على رف الكتب ، يمكنك إنشاء حقول التاريخ والوقت يدويًا (mysql):
table.dateTime('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP'))
table.dateTime('updated_at').defaultTo(knex.raw('NULL ON UPDATE CURRENT_TIMESTAMP'))
أو إذا كنت تفضل updated_at
على الإعداد الافتراضي لوقت الإنشاء أيضًا:
table.dateTime('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP'))
table.dateTime('updated_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
بدلاً من الاعتماد على رف الكتب ، يمكنك إنشاء حقول التاريخ والوقت يدويًا (mysql):
table.dateTime('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP')) table.dateTime('updated_at').defaultTo(knex.raw('NULL ON UPDATE CURRENT_TIMESTAMP'))
لا يزال استخدام الرمز الذي نشرته لـ updated_at مع القيمة الافتراضية الفارغة يدرج الطابع الزمني الحالي لـ updated_at.
const UserModel = bookshelf.Model.extend({
tableName: 'users',
hasTimestamps: ['createdAt', 'updatedAt'],
});
فشل هذا الاختبار:
it('doesntStoreUpdatedAtForCreation', async () => {
// arrange && act
const inserted = await new UserModel().save();
// assert
const retrievedModel = await UserModel.where({ id: inserted.id }).fetch();
assert.notExists(retrievedModel.get('updatedAt'));
});
يحرر:
لا بأس ، يبدو أن إزالة hasTimestamps
من تعريف النموذج يصلح هذا الأمر.
نحن نخلط بين مشكلات Knex و Bookshelf هنا ، ولكن @ Ice32 إذا كنت لا تريد استخدام ميزة الطابع الزمني التلقائي لـ Bookshelf ، hasTimestamps: ['createdAt', 'updatedAt']
من تعريف النموذج الخاص بك. سيعمل الرمز الذي نشره
بلدي الحل:
const Database = use("Database");
/*......*/
table
.timestamp("created_at")
.notNullable()
.defaultTo(Database.raw("CURRENT_TIMESTAMP"));
table
.timestamp("updated_at")
.notNullable()
.defaultTo(
Database.raw("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
);
أعتقد أن timestamps()
يحتاج إما إلى توفير وظيفة التحديث التلقائي هذه أو أن المستندات تحتاج إلى توضيح أنها لا تفعل ذلك. لقد افترضت ببساطة أن الوظيفة كانت سببًا حاسمًا لوجود طريقة timestamps()
على الإطلاق.
الطريقة timestamps()
غير مجدية بالنسبة لي لأنه لا يمكنني تعيين on update current_timestamp
.
التعليق الأكثر فائدة
أعتقد أن
timestamps()
يحتاج إما إلى توفير وظيفة التحديث التلقائي هذه أو أن المستندات تحتاج إلى توضيح أنها لا تفعل ذلك. لقد افترضت ببساطة أن الوظيفة كانت سببًا حاسمًا لوجود طريقةtimestamps()
على الإطلاق.