Sha256: 21a6e00ce01cf0d3f25d9e4ac4463f3dbbcae56ba5532bc799005834c85eaeb9

Contents?: true

Size: 1.94 KB

Versions: 1

Compression:

Stored size: 1.94 KB

Contents

module ForeignKeyValidation
  module ModelExtension
    extend ActiveSupport::Concern

    included do
      private
      def validate_foreign_key(validate_against_key, reflection_name)
        return if send(reflection_name).try(validate_against_key).nil? or try(validate_against_key).nil?

        if send(reflection_name).send(validate_against_key) != send(validate_against_key)
          errors.add(validate_against_key, "#{validate_against_key} of #{reflection_name} does not match #{self.class.name.tableize} #{validate_against_key}")
        end
      end
    end

    module ClassMethods
      def validate_foreign_keys(opt={})
        subclasses.map {|klass| klass.send(:validate_foreign_keys, opt) } if subclasses.any?

        validate_against      = (opt[:on] || :user).to_s
        validate_against_key  = "#{validate_against}_id"
        reflection_names      = reflect_on_all_associations(:belongs_to).map(&:name).map(&:to_s)
        validate_with         = ((Array(opt[:with]).map(&:to_s) if opt[:with]) || reflection_names).reject {|n| n == validate_against}

        raise ArgumentError, "Can't find any belongs_to relations for #{name} class. Put validation call below association definitions" if reflection_names.empty?
        raise ArgumentError, "No foreign key #{validate_against_key} on #{table_name} table!" unless reflection_names.include?(validate_against)
        raise ArgumentError, "Unknown relation in #{validate_with}!" unless validate_with.all? {|k| reflection_names.include?(k) }

        define_method "validate_foreign_keys_on_#{validate_against}" do
          validate_with.each do |reflection_name|
            validate_foreign_key(validate_against_key, reflection_name)
          end
        end
        private "validate_foreign_keys_on_#{validate_against}".to_sym

        before_validation "validate_foreign_keys_on_#{validate_against}"
      end
    end
  end
end

ActiveRecord::Base.send :include, ForeignKeyValidation::ModelExtension

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
foreign_key_validation-0.0.7 lib/foreign_key_validation/model_extension.rb