Coldbox and VueJS untangled

Category: quick

Quick create issues

Today one of my colleagues was working on some API project. He was creating some resources and just wanted to return the id of the value upon creation. So for example this call:

POST http://my.site/api/v1/company

should return the id of the newly created company. We are using the coldbox RestHandler and quick for database interaction, so we were expecting the following code would generate the desired result:

function create(event,rc,prc){
  //qCompany is a quick entity
  var oCompany = getInstance("qCompany").create({
    "name": "someCompany",
    "tenant_id": "1"
  });
  event.getResponse()
    .setData( { "id": oCompany.getId() } )
 	.setStatusCode( event.STATUS.CREATED )
	.addMessage( "Customer created" );   
}

Our VueJS frontend is expecting some integer number in the id data field. But to our surprise it was returning a string instead of a number. Not a big deal in some cases, but if you are more strict on your API you certainly want a number for an auto-incrementing key. So let me share some of the characteristics of our quick entity.

property name="id" column="company_id";
property name="name";
// db default for enabled = 1
property name="enabled" column ="enabled"; 
property name="tenant_id" column="tenant_id";

So nothing really special, an auto-incrementing id, some name, enabled which is 1 because of some db default and a tenant_id which is an integer number.

So what happens when you call getInstance("qCompany").create ? According to the docs there’s no need to call save()when calling create(), so I would assume we have an object with valid data now. But calling oCompany.getId() gives me a string instead of an integer, although it is a number? When entering data for my oCompany object I only entered a name and tenant_id, so let’s see what my object data looks like:

So I do have some Id, although it has the wrong datatype. The enabled property does not reflect the state in the database, it is empty. I entered my tenant_id as a string, so it is reflected here as a string. So it looks like it just showing us what we entered in our create function, except for the Id which just gets filled with some string.
Let’s see what happens if we create a second instance of this newly created item, by retrieving it from the database again. And as a final step we want to know if both instances are the same.

var myCompany = getInstance('qCompany@usermanagement')
  .create({
    "name":"someCompany",
    "tenant_id": "1" 
  });
var myCompany2 = getInstance('qCompany@usermanagement')
    .find(myCompany.getId());
writedump( 
  var = myCompany.issameAs(myCompany2), 
  label="sameAs"
);

The results:

Ok. So the enabled property is empty after creation, but if we retrieve the same entity from the database it has a value 1 as expected from our database default. Our Id has changed from string to a number and our tenant_id is also a number now. The funny thing is that the sameAs function thinks both instances are identical., although Id, tenant_id and enabled all return different data. In this case the function name promises more than the documentation which just tells us:

You can compare entities using the isSameAs and isNotSameAs methods. Each method takes another entity and returns true if the two objects represent the same entity.

So not exactly the same, but both representing the same entity. I guess that could give some confusion results if you are creating new entities. Luckily there is a very easy function to make sure sure it represents the data in the database: a simple call to myObject.refresh() will update all properties to the persisted values, but at the price of a database roundtrip.

I think at least the returned keyValue from getId() could use some better treatment in Quick. An auto-incrementing Key should never return a string if it is technically a number. Of course it is easy to fix by converting the ID to a number, changing the getId function or better yet, fix the auto-incrementing key in quick, of just create a new keyType which returns the correct data. We did a quick compare to Laravel, which just returns the correct datatype and value.
When comparing to cborm/cform the flexibility and ease-of-use in quick comes at a price. The handling of data types is a lot weaker, unless we start explicitly casting all properties in a quick entity. I did not test it yet, but I assume datatypes in cborm are more strict and it can also handle null values better.


Logbox: track your database changes (part 1)

As a former owner and CTO of a webhosting company our support staff and our customers often made changes to DNS and email settings in our CFML customer portal, but this can be a dangerous affair if you don’t know what your are doing . Of course auditing can be done in the database systems, but in that case you’ll often miss specific information such as user ID’s, company names, ip numbers and so on. In other projects a detailed log of our database changes could also be very useful, so in this post I’ll discuss how you can log your changes very easily using Logbox and interceptors in a coldbox application.

Continue reading

Use THIS in quick

Ok, this may sound like a somewhat cryptic title. We are talking about the importance of this, and now I mean the this keyword. To be honest I never worried too much about the this keyword. I know it is a component scope and when you refer to this inside your component, you refer to the public scope, so everything from this component which is visible to the outside world.

But now I had some issues (explanation will follow). I was surprised to see how hard it was to find a decent explanation of the this component scope. Not easy to google, because ‘this’ shows up in a lot of web pages…

Continue reading

Dynamic datasources part 2: quick

Using dynamic datasources in a cfml ORM system can be hard. I am working on some project full of cform, and as mentioned in my post on dynamic datasources in qb I have a project with a lot of legacy code, full of cfquery, queryExecute, some qb queries and… tons of cform entities. And for all this code I should be able to change my datasource on the fly, based on URL or the authenticated user. I already had all solutions in place for qb and queryExecute, but cform is a showstopper. Back in CF9 when cform was introduced you could only work with ONE datasource, the default datasource. Since default datasources where introduced in CF9 I suspect this was only done to accommodate for the lack of datasource awareness of the cf9.0 orm entities. In CF9.01 this became slightly better when we could specify some datasource property, but it has always been a pain to get this right. And unfortunately we often worked with a multidatasource setup. When we switched from Lucee 4 to 5 it took several years before a very important multi datasource bug was fixed. And now we even needed dynamic datasources, which is a real NO! in cform. So how about quick?

Continue reading

© 2024 ShiftInsert.nl

Theme by Anders NorenUp ↑