期待される:
table.timestamps()
にupdated_ts
列を作成する場合、その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
timestamp
列に.autoUpdate()
ビルダーメソッドが欲しいのですが、 .timestamps()
ヘルパーでもそれを有効にするのは簡単です。
SQLite3にも、これを実装するために使用できるトリガーがあるようです。 Oracleとmssqlには、より優れた構文がある場合もありますが、少なくともトリガーを使用して実行することもできます。
これはとてもいいでしょう! 現在、タイムスタンプを更新する本棚に依存する必要がありますか?
本棚に依存する代わりに、datetime-fieldsを手動で作成できます(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'))
本棚に依存する代わりに、datetime-fieldsを手動で作成できます(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の問題を混ぜ合わせていますが、 hasTimestamps: ['createdAt', 'updatedAt']
を削除する必要があります。 @codeclownが上に投稿したコードは、期待どおりに機能します。
私の解決策:
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()
メソッドが存在する主な理由は、機能であると単純に想定しました。
on update current_timestamp
設定できないため、 timestamps()
メソッドは役に立ちません。
最も参考になるコメント
timestamps()
は、この自動更新機能を提供する必要があるか、ドキュメントに提供されていないことを明示的に記載する必要があると思います。timestamps()
メソッドが存在する主な理由は、機能であると単純に想定しました。