how to simulate typecasting of ActiveRecord in non-AR classes?

Hi,

I have non-ActiveRecord Ruby classes that I use for numerical (and
other) processing as part of an API service.

I seem to recall that AR will cast attributes, say, from a params hash,
into the data type expected for the attribute. That is useful, and I'm
missing that feature in my non-AR classes. Has anyone considered this
challenge in their own work, and, if so, what mechanism (existing
modules or code snippets) would they propose as a way to introduce
casting?

Thanks,

Grar

Something along the lines of https://gist.github.com/1339540 (put it in the lib/ directory and include it in load path if needed) should work.

Then you just create a custom class, e.g. an ActiveModel class:

class CustomModel

include ActiveModel::Validations

include ActiveModel::Conversion

include ActiveModel::Serializers::JSON

include ActiveModel::Serializers::Xml

extend ActiveModel::Naming

include TypeCaster

field :id, Integer

field :name, String

field :description, String

field :some_integer, Integer

validates_presence_of :id, :name

validate_numericality_of :some_integer

def persisted?

false

end

end

Just doing this off the top of my head, so might be some typos in there, but you get the point.

I’d use this method so your custom classes at least have some notion of what to expect, that’s what ActiveRecord also does (using the database column types).

You can then just pass in a json hash to the constructor:

CustomModel.new(params)

where params is a json hash like {name: “John Doe”, id: 123, description: “Some anonymous man”, some_integer: 5}

Even if for some reason that some_integer would be passed in as a string, your custom model would still typecast it to an integer, since your model enforces it to.

Best regards

Peter De Berdt

I stand corrected, where params is a normal Ruby hash (my weekend has started, my mind is slowing down ;-))

Best regards

Peter De Berdt

Peter,

Wow, that's a lot!

One of my reasons for posting was I saw
ActiveModel::Serializers#from_json and I thought, 'What good is this, if
there is not some other facility to handle non-String attributes?' It
seems, though, that the functionality you have so generously sketched is
just not available via some overriding of AM modules.

Thanks,

Grar