Skip to content

Commit

Permalink
feat(Casts): Allow specifying virtual attributes with a cast
Browse files Browse the repository at this point in the history
An attribute may be marked as virtual to avoid trying to retrieve
or save it from the database while still allowing the entity and
memento to see it. (To correctly work, `getters` and `setters` should
be set as `false` on the property.)
  • Loading branch information
elpete committed May 31, 2024
1 parent c3c95ce commit a57d092
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 70 deletions.
2 changes: 1 addition & 1 deletion models/BaseEntity.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -3257,7 +3257,7 @@ component accessors="true" {
return arguments.value;
}

if ( isNullValue( arguments.key, arguments.value ) ) {
if ( !isVirtualAttribute( arguments.key ) && isNullValue( arguments.key, arguments.value ) ) {
return arguments.value;
}

Expand Down
10 changes: 10 additions & 0 deletions tests/resources/app/models/Address.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,14 @@ component accessors="true" {
return fullStreet() & chr( 10 ) & "#getCity()#, #getState()# #getZip()#";
}

function getMemento() {
return {
"streetOne": variables.streetOne,
"streetTwo": variables.streetTwo,
"city": variables.city,
"state": variables.state,
"zip": variables.zip
};
}

}
12 changes: 11 additions & 1 deletion tests/resources/app/models/User.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ component extends="quick.models.BaseEntity" accessors="true" {
property
name ="address"
casts ="AddressCast"
persistent="false"
virtual ="true"
getter ="false"
setter ="false";
property name="streetOne";
Expand All @@ -30,6 +30,16 @@ component extends="quick.models.BaseEntity" accessors="true" {
property name="state";
property name="zip";

this.memento = {
"neverInclude": [
"streetOne",
"streetTwo",
"city",
"state",
"zip"
]
};

function externalThings() {
return hasMany(
relationName = "externalThing",
Expand Down
21 changes: 21 additions & 0 deletions tests/specs/integration/BaseEntity/AttributeCastsSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,27 @@ component extends="tests.resources.ModuleIntegrationSpec" {
expect( user.getState() ).toBe( "TX" );
} );

it( "can assign a value object that is then casted", () => {
var user = getInstance( "User" );
user.setUsername( "testing_casts" );
user.setFirstName( "Testing" );
user.setLastName( "Casts" );
var newAddress = getInstance( "Address" );
newAddress.setStreetOne( "123 Elm Street" );
newAddress.setCity( "Salt Lake City" );
newAddress.setState( "UT" );
newAddress.setZip( "84123" );
user.setAddress( newAddress );
user.save();

var fetchedUser = getInstance( "User" ).where( "username", "testing_casts" ).firstOrFail();
expect( fetchedUser.getUsername() ).toBe( "testing_casts" );
expect( fetchedUser.getFirstName() ).toBe( "Testing" );
expect( fetchedUser.getLastName() ).toBe( "Casts" );
expect( fetchedUser.getAddress() ).notToBeNull();
expect( fetchedUser.getAddress().formatted() ).toBe( newAddress.formatted() );
} );

it( "can cast json data", function() {
var theme = getInstance( "Theme" ).create( {
"slug" : "my-theme",
Expand Down
69 changes: 35 additions & 34 deletions tests/specs/integration/BaseEntity/AttributeSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ component extends="tests.resources.ModuleIntegrationSpec" {

it( "shows all the attributes in the memento of a newly created object", function() {
var memento = getInstance( "User" ).getMemento();
if ( structCount( memento ) != 18 ) {
if ( structCount( memento ) != 14 ) {
var expected = [
"id",
"username",
Expand All @@ -111,11 +111,7 @@ component extends="tests.resources.ModuleIntegrationSpec" {
"type",
"email",
"externalID",
"streetOne",
"streetTwo",
"city",
"state",
"zip",
"address",
"favoritePost_id"
];
var missing = duplicate( expected );
Expand All @@ -126,7 +122,7 @@ component extends="tests.resources.ModuleIntegrationSpec" {
extra.append( key );
}
}
expect( structCount( memento ) ).toHaveLength( 18 );
expect( memento ).toHaveLength( 14 );
}
expect( memento ).toHaveKey( "id" );
expect( memento[ "id" ] ).toBe( "" );
Expand All @@ -152,39 +148,44 @@ component extends="tests.resources.ModuleIntegrationSpec" {
expect( memento[ "email" ] ).toBe( "" );
expect( memento ).toHaveKey( "externalId" );
expect( memento[ "externalId" ] ).toBe( "" );
expect( memento ).toHaveKey( "streetOne" );
expect( memento[ "streetOne" ] ).toBe( "" );
expect( memento ).toHaveKey( "streetTwo" );
expect( memento[ "streetTwo" ] ).toBe( "" );
expect( memento ).toHaveKey( "city" );
expect( memento[ "city" ] ).toBe( "" );
expect( memento ).toHaveKey( "state" );
expect( memento[ "state" ] ).toBe( "" );
expect( memento ).toHaveKey( "zip" );
expect( memento[ "zip" ] ).toBe( "" );
expect( memento ).toHaveKey( "address" );
var address = memento[ "address" ];
expect( address ).toBeStruct();
expect( address ).toHaveKey( "streetOne" );
expect( address[ "streetOne" ] ).toBe( "" );
expect( address ).toHaveKey( "streetTwo" );
expect( address[ "streetTwo" ] ).toBe( "" );
expect( address ).toHaveKey( "city" );
expect( address[ "city" ] ).toBe( "" );
expect( address ).toHaveKey( "state" );
expect( address[ "state" ] ).toBe( "" );
expect( address ).toHaveKey( "zip" );
expect( address[ "zip" ] ).toBe( "" );
expect( memento ).toHaveKey( "favoritePost_id" );
expect( memento[ "favoritePost_id" ] ).toBe( "" );
} );

it( "shows all the attributes in the component casing", function() {
expect( getInstance( "User" ).findOrFail( 1 ).getMemento() ).toBe( {
"id" : 1,
"username" : "elpete",
"firstName" : "Eric",
"lastName" : "Peterson",
"password" : "5F4DCC3B5AA765D61D8327DEB882CF99",
"countryId" : "02B84D66-0AA0-F7FB-1F71AFC954843861",
"teamId" : 1,
"createdDate" : "2017-07-28 02:06:36",
"modifiedDate" : "2017-07-28 02:06:36",
"type" : "admin",
"email" : "",
"externalId" : "1234",
"streetOne" : "123 Elm Street",
"streetTwo" : "",
"city" : "Salt Lake City",
"state" : "UT",
"zip" : "84123",
"id" : 1,
"username" : "elpete",
"firstName" : "Eric",
"lastName" : "Peterson",
"password" : "5F4DCC3B5AA765D61D8327DEB882CF99",
"countryId" : "02B84D66-0AA0-F7FB-1F71AFC954843861",
"teamId" : 1,
"createdDate" : "2017-07-28 02:06:36",
"modifiedDate" : "2017-07-28 02:06:36",
"type" : "admin",
"email" : "",
"externalId" : "1234",
"address" : {
"streetOne" : "123 Elm Street",
"streetTwo" : "",
"city" : "Salt Lake City",
"state" : "UT",
"zip" : "84123"
},
"favoritePost_id" : "1245"
} );
} );
Expand Down
72 changes: 38 additions & 34 deletions tests/specs/integration/BaseEntity/MementoSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,25 @@ component extends="tests.resources.ModuleIntegrationSpec" {
describe( "mementos", function() {
it( "returns an empty memento for a newly created entity", function() {
expect( getInstance( "User" ).getMemento() ).toBe( {
"id" : "",
"firstName" : "",
"lastName" : "",
"email" : "",
"username" : "",
"password" : "",
"type" : "",
"countryId" : "",
"teamId" : "",
"createdDate" : "",
"modifiedDate" : "",
"externalID" : "",
"streetOne" : "",
"streetTwo" : "",
"city" : "",
"state" : "",
"zip" : "",
"id" : "",
"firstName" : "",
"lastName" : "",
"email" : "",
"username" : "",
"password" : "",
"type" : "",
"countryId" : "",
"teamId" : "",
"createdDate" : "",
"modifiedDate" : "",
"externalID" : "",
"address" : {
"streetOne" : "",
"streetTwo" : "",
"city" : "",
"state" : "",
"zip" : ""
},
"favoritePost_id" : ""
} );
} );
Expand Down Expand Up @@ -48,23 +50,25 @@ component extends="tests.resources.ModuleIntegrationSpec" {
"publishedDate" : "2017-07-28 02:07:00",
"user_id" : "1",
"author" : {
"id" : "1",
"firstName" : "Eric",
"lastName" : "Peterson",
"email" : "",
"username" : "elpete",
"password" : "5F4DCC3B5AA765D61D8327DEB882CF99",
"type" : "admin",
"countryId" : "02B84D66-0AA0-F7FB-1F71AFC954843861",
"teamId" : 1,
"createdDate" : "2017-07-28 02:06:36",
"modifiedDate" : "2017-07-28 02:06:36",
"externalID" : "1234",
"streetOne" : "123 Elm Street",
"streetTwo" : "",
"city" : "Salt Lake City",
"state" : "UT",
"zip" : "84123",
"id" : "1",
"firstName" : "Eric",
"lastName" : "Peterson",
"email" : "",
"username" : "elpete",
"password" : "5F4DCC3B5AA765D61D8327DEB882CF99",
"type" : "admin",
"countryId" : "02B84D66-0AA0-F7FB-1F71AFC954843861",
"teamId" : 1,
"createdDate" : "2017-07-28 02:06:36",
"modifiedDate" : "2017-07-28 02:06:36",
"externalID" : "1234",
"address" : {
"streetOne" : "123 Elm Street",
"streetTwo" : "",
"city" : "Salt Lake City",
"state" : "UT",
"zip" : "84123"
},
"favoritePost_id" : "1245"
}
} );
Expand Down

0 comments on commit a57d092

Please sign in to comment.