diff --git a/models/BaseEntity.cfc b/models/BaseEntity.cfc index f2fa40e..f63141b 100644 --- a/models/BaseEntity.cfc +++ b/models/BaseEntity.cfc @@ -439,6 +439,15 @@ component accessors="true" { return arrayWrap( variables._key ); } + /** + * Returns the timestamp fields updated by `touch`. + * + * @return [String] + */ + public array function timestampFields() { + return [ "modifiedDate" ]; + } + /** * Returns the column name for the primary key. * @@ -1414,6 +1423,24 @@ component accessors="true" { return save(); } + /** + * Resets the entity to its clean state, updates its timestamp fields to the + * current time, and saves the entity. + * + * @options Any options to pass to `queryExecute`. Default: {}. + * + * @return quick.models.BaseEntity + */ + public any function touch( struct options = {} ) { + guardAgainstNotLoaded( "This instance is not loaded so it cannot be touched." ); + reset(); + var timestamp = now(); + timestampFields().each( function( field ) { + assignAttribute( arguments.field, timestamp ); + } ); + return save( arguments.options ); + } + /** * Creates a new entity with the given attributes and then saves the entity. * diff --git a/tests/resources/app/models/CustomTimestampUser.cfc b/tests/resources/app/models/CustomTimestampUser.cfc new file mode 100644 index 0000000..7c3866d --- /dev/null +++ b/tests/resources/app/models/CustomTimestampUser.cfc @@ -0,0 +1,15 @@ +component + extends ="quick.models.BaseEntity" + accessors="true" + table ="users" +{ + + property name="id"; + property name="createdDate" column="created_date"; + property name="modifiedDate" column="modified_date"; + + public array function timestampFields() { + return [ "createdDate" ]; + } + +} diff --git a/tests/specs/integration/BaseEntity/SaveSpec.cfc b/tests/specs/integration/BaseEntity/SaveSpec.cfc index 9ffc5f6..16af739 100644 --- a/tests/specs/integration/BaseEntity/SaveSpec.cfc +++ b/tests/specs/integration/BaseEntity/SaveSpec.cfc @@ -76,6 +76,34 @@ component extends="tests.resources.ModuleIntegrationSpec" { expect( userRowsPostSave ).toHaveLength( 5 ); } ); + it( "can touch an entity timestamp", function() { + var user = getInstance( "User" ).findOrFail( 1 ); + var originalModified = user.getModifiedDate(); + var originalFirstName = user.getFirstName(); + + user.setFirstName( "This must not be persisted" ); + + user.touch(); + + expect( dateCompare( user.getModifiedDate(), originalModified ) ).toBe( 1 ); + expect( user.getFirstName() ).toBe( originalFirstName ); + expect( user.isDirty( "modifiedDate" ) ).toBeFalse(); + var freshUser = user.fresh(); + expect( dateCompare( freshUser.getModifiedDate(), originalModified ) ).toBe( 1 ); + expect( freshUser.getFirstName() ).toBe( originalFirstName ); + } ); + + it( "can override the timestamp fields used by touch", function() { + var user = getInstance( "CustomTimestampUser" ).findOrFail( 1 ); + var originalCreated = user.getCreatedDate(); + var originalModified = user.getModifiedDate(); + + user.touch(); + + expect( dateCompare( user.getCreatedDate(), originalCreated ) ).toBe( 1 ); + expect( dateCompare( user.getModifiedDate(), originalModified ) ).toBe( 0 ); + } ); + it( "does not allow updating of column where update=false in property", function() { var existingUser = getInstance( "User" ).find( 1 ); existingUser.setEmail( "test2@test.com" );