Sha256: d898b39b21f3d8a540b2ebcb2b29adec01c28f7acd5c00f77bbb0fed0f4244bc

Contents?: true

Size: 1.54 KB

Versions: 6

Compression:

Stored size: 1.54 KB

Contents

module Rooftop
  module Coercions
    def self.included(base)
      # Include Rooftop::HookCalls to allow us to push things into a list of hooks in the right order
      base.include Rooftop::HookCalls
      base.extend ClassMethods

      # Add the call to the :after_find hook to the list of hook calls, to be processed later.
      # This is where we iterate over our previously established list of coercions, and call each
      # in turn
      base.send(:add_to_hook, :after_find, ->(r){
        r.coercions.each do |field,coercion|
          if r.respond_to?(field)
            r.send("#{field}=",coercion.call(r.send(field)))
          end
        end
      })
      base.send(:before_save, ->(r) {
        r.coercions.each do |field,coercion|
          r.send(:"restore_#{field}!") unless r.new?
        end
      })
    end

    module ClassMethods
      # Call coerce_field() in a class to do something with the attribute. Useful for parsing dates etc.
      # For example: coerce_field(date: ->(date_string) { DateTime.parse(date_string)}) to get a DateTime object from a string field. The date field will now be a DateTime.

      # @param coercion [Hash] the coercion to apply - key is the field, value is a lambda
      def coerce_field(*coercions)
        @coercions ||= {}
        coercions.each do |coercions_hash|
          @coercions.merge!(coercions_hash)
        end
        @coercions
      end
    end

    # Instance method to get the class's coercions
    def coercions
      self.class.instance_variable_get(:"@coercions") || {}
    end
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
rooftop-0.1.4.1 lib/rooftop/coercions.rb
rooftop-0.1.4 lib/rooftop/coercions.rb
rooftop-0.1.3 lib/rooftop/coercions.rb
rooftop-0.1.2 lib/rooftop/coercions.rb
rooftop-0.1.1 lib/rooftop/coercions.rb
rooftop-0.0.7.4 lib/rooftop/coercions.rb