<commit_before>module Audited
  # Specify this act if you want changes to your model to be saved in an
  # audit table.  This assumes there is an audits table ready.
  #
  #   class User < ActiveRecord::Base
  #     audited
  #   end
  #
  # To store an audit comment set model.audit_comment to your comment before
  # a create, update or destroy operation.
  #
  # See <tt>Audited::Adapters::ActiveRecord::Auditor::ClassMethods#audited</tt>
  # for configuration options
  module Auditor #:nodoc:
    extend ActiveSupport::Concern

    CALLBACKS = [:audit_create, :audit_update, :audit_destroy]

    module ClassMethods
      # == Configuration options
      #
      #
      # * +only+ - Only audit the given attributes
      # * +except+ - Excludes fields from being saved in the audit log.
      #   By default, Audited will audit all but these fields:
      #
      #     [self.primary_key, inheritance_column, 'lock_version', 'created_at', 'updated_at']
      #   You can add to those by passing one or an array of fields to skip.
      #
      #     class User < ActiveRecord::Base
      #       audited :except => :password
      #     end
      #
      # * +require_comment+ - Ensures that audit_comment is supplied before
      #   any create, update or destroy operation.
      #
      def audited(options = {})
        # don't allow multiple calls
        return if self.included_modules.include?(Audited::Auditor::AuditedInstanceMethods)

        class_attribute :non_audited_columns,   :instance_writer => false
        class_attribute :auditing_enabled,      :instance_writer => false
        class_attribute :audit_associated_with, :instance_writer => false

        if options[:only]
          except = self.column_names - options[:only].flatten.map(&:to_s)
        else
          except = default_ignored_attributes + Audited.ignored_attributes
          except |= Array(options[:except]).collect(&:to_s) if options[:except]
        end
        self.non_audited_columns = except
        self.audit_associated_with = options[:associated_with]

        if options[:comment_required]
          validates_presence_of :audit_comment, :if => :auditing_enabled
          before_destroy :require_comment
        end

        attr_accessor :audit_comment

        has_many :audits, :as => :auditable, :class_name => Audited.audit_class.name
        Audited.audit_class.audited_class_names << self.to_s

        after_create  :audit_create if !options[:on] || (options[:on] && options[:on].include?(:create))
        before_update :audit_update if !options[:on] || (options[:on] && options[:on].include?(:update))
        before_destroy :audit_destroy if !options[:on] || (options[:on] && options[:on].include?(:destroy))

        # Define and set after_audit and around_audit callbacks. This might be useful if you want
        # to notify a party after the audit has been created or if you want to access the newly-created
        # audit.
        define_callbacks :audit
        set_callback :audit, :after, :after_audit, :if => lambda { self.respond_to?(:after_audit) }
        set_callback :audit, :around, :around_audit, :if => lambda { self.respond_to?(:around_audit) }

        attr_accessor :version

        extend Audited::Auditor::AuditedClassMethods
        include Audited::Auditor::AuditedInstanceMethods

        self.auditing_enabled = true
      end

      def has_associated_audits
        has_many :associated_audits, :as => :associated, :class_name => Audited.audit_class.name
      end
    end

    module AuditedInstanceMethods
      # Temporarily turns off auditing while saving.
      def save_without_auditing
        without_auditing { save }
      end

      # Executes the block with the auditing callbacks disabled.
      #
      #   @foo.without_auditing do
      #     @foo.save
      #   end
      #
      def without_auditing(&block)
        self.class.without_auditing(&block)
      end

      # Gets an array of the revisions available
      #
      #   user.revisions.each do |revision|
      #     user.name
      #     user.version
      #   end
      #
      def revisions(from_version = 1)
        audits = self.audits.from_version(from_version)
        return [] if audits.empty?
        revisions = []
        audits.each do |audit|
          revisions << audit.revision
        end
        revisions
      end

      # Get a specific revision specified by the version number, or +:previous+
      def revision(version)
        revision_with Audited.audit_class.reconstruct_attributes(audits_to(version))
      end

      # Find the oldest revision recorded prior to the date/time provided.
      def revision_at(date_or_time)
        audits = self.audits.up_until(date_or_time)
        revision_with Audited.audit_class.reconstruct_attributes(audits) unless audits.empty?
      end

      # List of attributes that are audited.
      def audited_attributes
        attributes.except(*non_audited_columns)
      end

      protected

      def revision_with(attributes)
        self.dup.tap do |revision|
          revision.id = id
          revision.send :instance_variable_set, '@attributes', self.attributes if rails_below?('4.2.0')
          revision.send :instance_variable_set, '@new_record', self.destroyed?
          revision.send :instance_variable_set, '@persisted', !self.destroyed?
          revision.send :instance_variable_set, '@readonly', false
          revision.send :instance_variable_set, '@destroyed', false
          revision.send :instance_variable_set, '@_destroyed', false
          revision.send :instance_variable_set, '@marked_for_destruction', false
          Audited.audit_class.assign_revision_attributes(revision, attributes)

          # Remove any association proxies so that they will be recreated
          # and reference the correct object for this revision. The only way
          # to determine if an instance variable is a proxy object is to
          # see if it responds to certain methods, as it forwards almost
          # everything to its target.
          for ivar in revision.instance_variables
            proxy = revision.instance_variable_get ivar
            if !proxy.nil? and proxy.respond_to? :proxy_respond_to?
              revision.instance_variable_set ivar, nil
            end
          end
        end
      end

      def rails_below?(rails_version)
        Rails.gem_version < Gem::Version.new(rails_version)
      end

      private<commit_msg>Rails version check improved<commit_after>module Audited
  # Specify this act if you want changes to your model to be saved in an
  # audit table.  This assumes there is an audits table ready.
  #
  #   class User < ActiveRecord::Base
  #     audited
  #   end
  #
  # To store an audit comment set model.audit_comment to your comment before
  # a create, update or destroy operation.
  #
  # See <tt>Audited::Adapters::ActiveRecord::Auditor::ClassMethods#audited</tt>
  # for configuration options
  module Auditor #:nodoc:
    extend ActiveSupport::Concern

    CALLBACKS = [:audit_create, :audit_update, :audit_destroy]

    module ClassMethods
      # == Configuration options
      #
      #
      # * +only+ - Only audit the given attributes
      # * +except+ - Excludes fields from being saved in the audit log.
      #   By default, Audited will audit all but these fields:
      #
      #     [self.primary_key, inheritance_column, 'lock_version', 'created_at', 'updated_at']
      #   You can add to those by passing one or an array of fields to skip.
      #
      #     class User < ActiveRecord::Base
      #       audited :except => :password
      #     end
      #
      # * +require_comment+ - Ensures that audit_comment is supplied before
      #   any create, update or destroy operation.
      #
      def audited(options = {})
        # don't allow multiple calls
        return if self.included_modules.include?(Audited::Auditor::AuditedInstanceMethods)

        class_attribute :non_audited_columns,   :instance_writer => false
        class_attribute :auditing_enabled,      :instance_writer => false
        class_attribute :audit_associated_with, :instance_writer => false

        if options[:only]
          except = self.column_names - options[:only].flatten.map(&:to_s)
        else
          except = default_ignored_attributes + Audited.ignored_attributes
          except |= Array(options[:except]).collect(&:to_s) if options[:except]
        end
        self.non_audited_columns = except
        self.audit_associated_with = options[:associated_with]

        if options[:comment_required]
          validates_presence_of :audit_comment, :if => :auditing_enabled
          before_destroy :require_comment
        end

        attr_accessor :audit_comment

        has_many :audits, :as => :auditable, :class_name => Audited.audit_class.name
        Audited.audit_class.audited_class_names << self.to_s

        after_create  :audit_create if !options[:on] || (options[:on] && options[:on].include?(:create))
        before_update :audit_update if !options[:on] || (options[:on] && options[:on].include?(:update))
        before_destroy :audit_destroy if !options[:on] || (options[:on] && options[:on].include?(:destroy))

        # Define and set after_audit and around_audit callbacks. This might be useful if you want
        # to notify a party after the audit has been created or if you want to access the newly-created
        # audit.
        define_callbacks :audit
        set_callback :audit, :after, :after_audit, :if => lambda { self.respond_to?(:after_audit) }
        set_callback :audit, :around, :around_audit, :if => lambda { self.respond_to?(:around_audit) }

        attr_accessor :version

        extend Audited::Auditor::AuditedClassMethods
        include Audited::Auditor::AuditedInstanceMethods

        self.auditing_enabled = true
      end

      def has_associated_audits
        has_many :associated_audits, :as => :associated, :class_name => Audited.audit_class.name
      end
    end

    module AuditedInstanceMethods
      # Temporarily turns off auditing while saving.
      def save_without_auditing
        without_auditing { save }
      end

      # Executes the block with the auditing callbacks disabled.
      #
      #   @foo.without_auditing do
      #     @foo.save
      #   end
      #
      def without_auditing(&block)
        self.class.without_auditing(&block)
      end

      # Gets an array of the revisions available
      #
      #   user.revisions.each do |revision|
      #     user.name
      #     user.version
      #   end
      #
      def revisions(from_version = 1)
        audits = self.audits.from_version(from_version)
        return [] if audits.empty?
        revisions = []
        audits.each do |audit|
          revisions << audit.revision
        end
        revisions
      end

      # Get a specific revision specified by the version number, or +:previous+
      def revision(version)
        revision_with Audited.audit_class.reconstruct_attributes(audits_to(version))
      end

      # Find the oldest revision recorded prior to the date/time provided.
      def revision_at(date_or_time)
        audits = self.audits.up_until(date_or_time)
        revision_with Audited.audit_class.reconstruct_attributes(audits) unless audits.empty?
      end

      # List of attributes that are audited.
      def audited_attributes
        attributes.except(*non_audited_columns)
      end

      protected

      def revision_with(attributes)
        self.dup.tap do |revision|
          revision.id = id
          revision.send :instance_variable_set, '@attributes', self.attributes if rails_below?('4.2.0')
          revision.send :instance_variable_set, '@new_record', self.destroyed?
          revision.send :instance_variable_set, '@persisted', !self.destroyed?
          revision.send :instance_variable_set, '@readonly', false
          revision.send :instance_variable_set, '@destroyed', false
          revision.send :instance_variable_set, '@_destroyed', false
          revision.send :instance_variable_set, '@marked_for_destruction', false
          Audited.audit_class.assign_revision_attributes(revision, attributes)

          # Remove any association proxies so that they will be recreated
          # and reference the correct object for this revision. The only way
          # to determine if an instance variable is a proxy object is to
          # see if it responds to certain methods, as it forwards almost
          # everything to its target.
          for ivar in revision.instance_variables
            proxy = revision.instance_variable_get ivar
            if !proxy.nil? and proxy.respond_to? :proxy_respond_to?
              revision.instance_variable_set ivar, nil
            end
          end
        end
      end

      def rails_below?(rails_version)
        Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new(rails_version)
      end

      private
{'fraction_non_alphanumeric': 0.08257447136903844, 'fraction_numerical': 0.0006173792251890724, 'mean_word_length': 2.6360830527497194, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4516276', 'n_tokens_mistral': 3692, 'n_tokens_neox': 3602, 'n_words': 988}