diff --git a/models/BaseEntity.cfc b/models/BaseEntity.cfc index a3f7a943..9d484c39 100644 --- a/models/BaseEntity.cfc +++ b/models/BaseEntity.cfc @@ -848,11 +848,28 @@ component accessors="true" { } /** - * Returns if the entity has been edited since being loaded from the database. + * Returns if the entity, or one specific attribute, has been edited since + * being loaded from the database. + * + * @attribute An optional attribute alias or column name to inspect. * * @return Boolean */ - public boolean function isDirty() { + public boolean function isDirty( string attribute ) { + if ( !isNull( arguments.attribute ) ) { + guardAgainstNonExistentAttribute( arguments.attribute ); + var column = retrieveColumnForAlias( arguments.attribute ); + var currentAttributes = retrieveAttributesData( withNulls = true ); + var originalAttribute = {}; + var currentAttribute = {}; + if ( variables._originalAttributes.keyExists( column ) ) { + originalAttribute[ column ] = variables._originalAttributes[ column ]; + } + if ( currentAttributes.keyExists( column ) ) { + currentAttribute[ column ] = currentAttributes[ column ]; + } + return compare( computeAttributesHash( originalAttribute ), computeAttributesHash( currentAttribute ) ) != 0; + } param variables._originalAttributesHash = computeAttributesHash( variables._originalAttributes ); return compare( variables._originalAttributesHash, computeAttributesHash( retrieveAttributesData() ) ) != 0; } diff --git a/tests/specs/integration/BaseEntity/IsDirtySpec.cfc b/tests/specs/integration/BaseEntity/IsDirtySpec.cfc index d976c894..6e1c41a7 100644 --- a/tests/specs/integration/BaseEntity/IsDirtySpec.cfc +++ b/tests/specs/integration/BaseEntity/IsDirtySpec.cfc @@ -17,6 +17,26 @@ component extends="tests.resources.ModuleIntegrationSpec" { user.fill( { "last_name" : "Peterson" } ); expect( user.isDirty() ).toBeFalse(); } ); + + it( "can check whether a specific attribute alias or column is dirty", function() { + var user = getInstance( "User" ).findOrFail( 1 ); + + expect( user.isDirty( "username" ) ).toBeFalse(); + expect( user.isDirty( "firstName" ) ).toBeFalse(); + expect( user.isDirty( "first_name" ) ).toBeFalse(); + + user.setUsername( "updated-username" ); + expect( user.isDirty( "username" ) ).toBeTrue(); + expect( user.isDirty( "firstName" ) ).toBeFalse(); + + user.setFirstName( "Updated" ); + expect( user.isDirty( "firstName" ) ).toBeTrue(); + expect( user.isDirty( "first_name" ) ).toBeTrue(); + + user.setUsername( "elpete" ); + expect( user.isDirty( "username" ) ).toBeFalse(); + expect( user.isDirty() ).toBeTrue(); + } ); } ); }