Sha256: 871d2cc23b3ddcb076f6611d44440ee412d450c5457d4797f6ef66c4fe96d16a

Contents?: true

Size: 1.97 KB

Versions: 4

Compression:

Stored size: 1.97 KB

Contents

module TemporalTables
  # Stores the time from the "at" field into each of the resulting objects
  # so that it can be carried forward in subsequent queries.
  module RelationExtensions
    def self.included(base)
      base.class_eval do
        ActiveRecord::Relation::SINGLE_VALUE_METHODS << :at
      end
    end

    def at_value
      case Rails::VERSION::MINOR
      when 0
        @values.fetch(:at, nil) || Thread.current[:at_time]
      else
        get_value(:at) || Thread.current[:at_time]
      end
    end

    def at_value=(value)
      case Rails::VERSION::MINOR
      when 0
        @values[:at] = value
      else
        set_value(:at, value)
      end
    end

    def at(*args)
      spawn.at!(*args)
    end

    def at!(value)
      self.at_value = value
      self.where!(klass.build_temporal_constraint(value))
    end

    def to_sql(*args)
      threadify_at do
        super *args
      end
    end

    def threadify_at
      if at_value && !Thread.current[:at_time]
        Thread.current[:at_time] = at_value
        result = yield
        Thread.current[:at_time] = nil
      else
        result = yield
      end
      result
    end

    def limited_ids_for(*args)
      threadify_at do
        super *args
      end
    end

    def exec_queries
      # Note that record preloading, like when you specify
      #  MyClass.includes(:associations)
      # happens within this exec_queries call.  That's why we needed to
      # store the at_time in the thread above.
      threadify_at do
        super
      end

      if historical?
        # Store the at value on each record returned
        @records.each do |r|
          r.at_value = at_value
        end
      end
      @records
    end

    def historical?
      table_name =~ /_h$/i && at_value
    end

    # Only needed for Rails 5.1.x
    def default_value_for(name)
      if name == :at
        nil
      else
        super(name)
      end
    end
  end
end

ActiveRecord::Relation.prepend TemporalTables::RelationExtensions

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
temporal_tables-0.8.1 lib/temporal_tables/relation_extensions.rb
temporal_tables-0.8.0 lib/temporal_tables/relation_extensions.rb
temporal_tables-0.7.1 lib/temporal_tables/relation_extensions.rb
temporal_tables-0.7.0 lib/temporal_tables/relation_extensions.rb