Sha256: 5e8ff5f6eaf7b4961a7e880f27c69b902c2877cdd4746e9a621960ae0a4a0f82

Contents?: true

Size: 1.67 KB

Versions: 1

Compression:

Stored size: 1.67 KB

Contents

require 'active_record'

module ActiveRecord
  class Base
    class_attribute :key_attributes
    class << self
      def natural_key(*key_attributes)
        # TODO validate the supplied key_attributes are subset of all attributes
        # TODO key_attributes should default to primary_key/surrogate_key (:id)
        # TODO if natural_key is composed of non-primary-key, then it should not contain primary_key
        raise "natural key attributes cannot be empty" if key_attributes.empty?
        self.key_attributes = key_attributes
      end
      # can't use method "create_or_update" since there is already a private method with that name
      # in ActiveRecord::Base
      # TODO The following method should only be made available when natural_key is called with proper
      # attributes. (hint: use class_eval?)
      def create_or_update_by_natural_key(options)
        record = locate_record(options)
        if(record.nil?)
          record = create(options)
        else
          record.update_attributes(options)
        end
        record
      end

      def create_or_update_by_natural_key!(options)
        record = locate_record(options)
        if(record.nil?)
          record = create!(options)
        else
          record.update_attributes!(options)
        end
        record
      end

      private

      def locate_record(options)
        options.symbolize_keys!
        #TODO options should contain all key_attributes, and their values should be non-nil
        key_options = options.reject { |k,v| !key_attributes.include?(k) }
        raise "key_options cannot be empty" if key_options.empty?
        find(:first, :conditions => key_options)
      end

    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
natural_key-1.0.0 lib/natural_key/base.rb