Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 28 additions & 4 deletions models/BaseEntity.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -2914,22 +2914,43 @@ component accessors="true" {
/**
* Creates a virtual attribute for the given name.
*
* @name The attribute name to create.
* @name The attribute name to create.
* @defaultValue The default value for the virtual attribute.
* @excludeFromMemento Whether to exclude the virtual attribute from mementos.
*
* @return quick.models.BaseEntity
*/
public any function appendVirtualAttribute( required string name, boolean excludeFromMemento = false ) {
public any function appendVirtualAttribute(
required string name,
any defaultValue,
boolean excludeFromMemento = false
) {
if ( !variables._attributes.keyExists( retrieveAliasForColumn( arguments.name ) ) ) {
var attr = paramAttribute( {
var attributeDefinition = {
"name" : arguments.name,
"virtual" : true,
"exclude" : arguments.excludeFromMemento
} );
};
if ( arguments.keyExists( "defaultValue" ) ) {
attributeDefinition.default = arguments.defaultValue;
}
var attr = paramAttribute( attributeDefinition );
variables._attributes[ attr.name ] = attr;
variables._columns[ attr.column ] = attr;
variables._meta.attributes[ arguments.name ] = variables._attributes[ arguments.name ];
variables._meta.originalMetadata.properties.append( variables._attributes[ arguments.name ] );
variables._virtualAttributes.append( arguments.name );
if (
!arguments.excludeFromMemento &&
structKeyExists( this, "memento" ) &&
structKeyExists( this.memento, "defaultIncludes" ) &&
!arrayContainsNoCase( this.memento.defaultIncludes, arguments.name )
) {
this.memento.defaultIncludes.append( arguments.name );
}
if ( arguments.keyExists( "defaultValue" ) ) {
forceAssignAttribute( arguments.name, arguments.defaultValue );
}
}
return this;
}
Expand Down Expand Up @@ -2993,6 +3014,9 @@ component accessors="true" {
var attr = paramAttribute( arguments.attributes[ alias ] );
variables._attributes[ attr.name ] = attr;
variables._columns[ attr.column ] = attr;
if ( attr.virtual && attr.keyExists( "default" ) ) {
forceAssignAttribute( attr.name, attr.default );
}
if ( attr.convertToNull ) {
variables._nullValues[ alias ] = attr.nullValue;
}
Expand Down
10 changes: 8 additions & 2 deletions models/QuickBuilder.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -922,11 +922,17 @@ component accessors="true" transientCache="false" {
/**
* Creates a virtual attribute for the given name.
*
* @name The attribute name to create.
* @name The attribute name to create.
* @defaultValue The default value for the virtual attribute.
* @excludeFromMemento Whether to exclude the virtual attribute from mementos.
*
* @return quick.models.BaseEntity
*/
public any function appendVirtualAttribute( required string name, boolean excludeFromMemento = false ) {
public any function appendVirtualAttribute(
required string name,
any defaultValue,
boolean excludeFromMemento = false
) {
getEntity().appendVirtualAttribute( argumentCollection = arguments );
return this;
}
Expand Down
17 changes: 17 additions & 0 deletions tests/specs/integration/BaseEntity/AttributeSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ component extends="tests.resources.ModuleIntegrationSpec" {
expect( attributesFromFresh ).notToInclude( "latestPostId" );
} );

it( "can provide a default for a virtual attribute", function() {
var user = getInstance( "User" ).appendVirtualAttribute( "hasPosts", false );
var newUser = user.newEntity();

expect( serializeJSON( user.getHasPosts() ) ).toBe( "false" );
expect( serializeJSON( user.getMemento().hasPosts ) ).toBe( "false" );
expect( serializeJSON( newUser.getHasPosts() ) ).toBe( "false" );
expect( serializeJSON( newUser.getMemento().hasPosts ) ).toBe( "false" );
} );

it( "can exclude a defaulted virtual attribute from mementos", function() {
var user = getInstance( "User" ).appendVirtualAttribute( "internalFlag", false, true );

expect( serializeJSON( user.getInternalFlag() ) ).toBe( "false" );
expect( user.getMemento() ).notToHaveKey( "internalFlag" );
} );

it( "can get any attribute using the `getColumnName` magic methods", function() {
var user = getInstance( "User" ).find( 1 );
expect( user.getId() ).toBe( 1 );
Expand Down
Loading