Arjeno/stored_attribute

View on GitHub
lib/stored_attribute.rb

Summary

Maintainability
A
45 mins
Test Coverage
require "active_record"
require "stored_attribute/version"

module StoredAttribute

  extend ActiveSupport::Concern

  included do

    class_attribute :type_casted_attributes

  end

  module ClassMethods

    def attribute(key, options)
      self.type_casted_attributes ||= {}
      self.type_casted_attributes[key] = options

      getter    = "#{key}"
      setter    = "#{getter}="
      get_alias = "original_#{getter}"
      set_alias = "#{get_alias}="

      # Rename old methods to keep them accessible
      alias_method get_alias, getter
      alias_method set_alias, setter

      column = ActiveRecord::ConnectionAdapters::Column.new(key, options[:default], options[:type].to_s)

      define_method(getter) do
        value = send(get_alias)
        value.nil? ? column.default : column.type_cast(value)
      end

      define_method(setter) do |value|
        send(set_alias, column.type_cast(value))
      end

      # Set default values
      if ! options[:default].nil?
        after_initialize "set_default_#{getter}"

        define_method("set_default_#{getter}") do
          self.send(setter, options[:default]) if self.send(get_alias).nil?
        end
      end
    end

  end

end

ActiveRecord::Base.send(:include, StoredAttribute)