Custom type-casting with ActiveRecord, Virtus and dry-types

Your ads will be inserted here by

Easy Plugin for AdSense.

Please go to the plugin admin page to
Paste your ad code OR
Suppress this ad slot.

In Drop this before validation and just use a setter method I showed you how to avoid a common pattern of using before_validation to fix the data. Instead I proposed you just overwrite the setter, call your custom logic there and use super. I also showed you what you can do if you can’t easily call super .

But sometimes to properly transform the incoming data or attributes you just need to improve the type-casting logic. And that’s it. So let’s see how you can add your custom typecasting rules to a project.

And let’s continue with the simple example of stripped string.

Active Record 4.2+

class StrippedString < ActiveRecord::Type::String   def cast_value(value)     value.to_s.strip   end end 
class Post < ActiveRecord::Base   attribute :title, StrippedString.new end 
p = Post.new(title: " Use Rails ") p.title # => "Use Rails" 

Virtus

class StrippedString < Virtus::Attribute   def coerce(value)     value.to_s.strip   end end 
class Address   include Virtus.model   include ActiveModel::Validations    attribute :country_code, String   attribute :street,       StrippedString   attribute :zip_code,     StrippedString   attribute :city,         StrippedString   attribute :full_name,    StrippedString    validates :country_code,     :street,     :zip_code,     :city,     :full_name,     presence: true end 

Your ads will be inserted here by

Easy Plugin for AdSense.

Please go to the plugin admin page to
Paste your ad code OR
Suppress this ad slot.

a = Address.new(city: " Wrocław ") a.city # => "Wrocław" 

dry-types 0.6

module Types   include Dry::Types.module   StrippedString = String.constructor(->(val){ String(val).strip }) end 
class Post < Dry::Types::Struct   attribute :title, Types::StrippedString end 
p = Post.new(title: " Use dry ") p.title # => "Use dry" 

Conclusion

If you want to improve type casting for you Active Record class or if you need it for a different layer (e.g. a Form Object or Command Object) in both cases you are covered.

Historically, we have been using Virtus for that non-persistable layers. But with the recent release of dry-types (part of dry-rb) we started also investigating this angle as it looks very promising. I am very happy with the improvements added between 0.5 and 0.6 release. Definitelly a step in a right direction.

Summary

That’s it. That’s the entire lesson. If you want more free lessons how to improve your Rails codebase, subscribe to our mailing list below. We will regularly send you valuable tips and tricks. 3200 developers already trusted us.

More

Did you like this article? You will definitely find our Rails books interesting as well .

Custom type-casting with ActiveRecord, Virtus and dry-typesCustom type-casting with ActiveRecord, Virtus and dry-types

Leave a Reply

Your email address will not be published. Required fields are marked *