Back to Overview
Article Image
Article Image
read

So I’m going to keep this post relatively brief. This is about an attribute type issue I was experiencing while building an ember app with a rails backend using the very helpful Active Model Serializers gem with their JSON API adapter configuration to serve data. In this project we had a Rails model with a column that was a BigDecimal data type. I had some difficulties in dealing with this data type because I was unaware of the way the Active Model Serializers treats Rails BigDecimals, combined with some mistaken assumptions about how Ember handles transformations of data types. Hopefully this can help you avoid the pain I experienced.

TLDR; active model serializers return BigDecimals as a string and if you do not define a transform on your attribute in Ember you may end up working with strings when you expect numbers.

When I first started working with Ember I thought that you had to define a transform for all of your attributes in a model by providing them as an argument to your attr methods. In other words, to borrow an example from the Ember Guides:

import Model from 'ember-data/model';
import attr from 'ember-data/attr';

export default Model.extend({
  name: attr('string'),
  age: attr('number'),
  admin: attr('boolean'),
  birthday: attr('date')
});

This is not the case. You do not have to define a transform for your attr methods. Ember will just pass through the value of the data it’s consuming from the server.

import Model from 'ember-data/model';
import attr from 'ember-data/attr';

export default Model.extend({
  name: attr(),
  age: attr(),
  admin: attr(),
  birthday: attr()
});

Once I realized this I felt liberated from the constraint of having to explicitly define a transform for each attribute in each of my ember models (which are almost always duplicating a Rails-based model). Given the fact that some models in our projects have an ever growing list of attributes this felt especially good. Active Model Serializers seem to do a very good job at handling the treatment of most data types by default. So good in fact that I had never really had a problem with data types in Ember as they relate to our corresponding Rails models. This might cause you to think: Awesome! I’ll just not define a transform for any of my Ember attributes then.

In most situations this works fine. However, I did run into an issue when attempting to use a computed macro in Ember to sum the instances of the values being returned by the Rails server from the column with the BigDecimal data type. Should be easy right? Something like this:

Ember.computed.sum("someBigDecimalAttribute")

BUT … the computed macro was returning a very strange looking number:

99.90889.13

Hrrrmm. Given that the operation of the macro is a relatively simple sum function I could not make sense of what was going on. I spent a good bit of time trying to debug this result making several mistaken assumptions, including that perhaps it had something to do with a failure to resolve promises. Eventually I realized that what I was getting was the sum of two strings:

'99.90' + '889.13' = 99.90889.13

This was occurring because active model serializers was returning the BigDecimal column data as a string and Ember’s computed sum macro was just returning the summation of those strings. The most clear fix that I could think of was to explicitly define the transform on the Ember attribute as a number:

someBigDecimalAttribute: attr("number")

Excellent, that works! The computed macro is now returning the sum of the numbers 989.03 as it should.

Now this is probably obvious from the outset to many who know more about these issues than I do, but I do hope this is helpful to those newly approaching transforms in Ember and saves you a little time.

Blog Logo

Jared Galanis


Published

Image

Jared Galanis | a/web/dev/blog

This is the blog of Jared Galanis, a web developer working mainly in Ruby and JavaScript