class ActiveRecord::Import::Validator
def initialize(options = {})
def initialize(options = {}) @options = options end
def valid_model?(model)
def valid_model?(model) validation_context = @options[:validate_with_context] validation_context ||= (model.new_record? ? :create : :update) current_context = model.send(:validation_context) begin model.send(:validation_context=, validation_context) model.errors.clear validate_callbacks = model._validate_callbacks.dup associations = model.class.reflect_on_all_associations(:belongs_to).map(&:name) model._validate_callbacks.each do |callback| filter = callback.raw_filter if (!@options[:validate_uniqueness] && filter.is_a?(ActiveRecord::Validations::UniquenessValidator)) || (defined?(ActiveRecord::Validations::PresenceValidator) && filter.is_a?(ActiveRecord::Validations::PresenceValidator) && associations.include?(filter.attributes.first)) validate_callbacks.delete(callback) end end model.run_callbacks(:validation) do if defined?(ActiveSupport::Callbacks::Filters::Environment) # ActiveRecord >= 4.1 runner = validate_callbacks.compile env = ActiveSupport::Callbacks::Filters::Environment.new(model, false, nil) if runner.respond_to?(:call) # ActiveRecord < 5.1 runner.call(env) else # ActiveRecord 5.1 # Note that this is a gross simplification of ActiveSupport::Callbacks#run_callbacks. # It's technically possible for there to exist an "around" callback in the # :validate chain, but this would be an aberration, since Rails doesn't define # "around_validate". Still, rather than silently ignoring such callbacks, we # explicitly raise a RuntimeError, since activerecord-import was asked to perform # validations and it's unable to do so. # # The alternative here would be to copy-and-paste the bulk of the # ActiveSupport::Callbacks#run_callbacks method, which is undesirable if there's # no real-world use case for it. raise "The :validate callback chain contains an 'around' callback, which is unsupported" unless runner.final? runner.invoke_before(env) runner.invoke_after(env) end elsif validate_callbacks.method(:compile).arity == 0 # ActiveRecord = 4.0 model.instance_eval validate_callbacks.compile else # ActiveRecord 3.x model.instance_eval validate_callbacks.compile(nil, model) end end model.errors.empty? ensure model.send(:validation_context=, current_context) end end