<commit_before>require "remotable/core_ext"
require "active_support/concern"


module Remotable
  module ActiveRecordExtender
    extend ActiveSupport::Concern
    
    
    
    included do
      before_update   :update_remote_resource,  :unless => :nosync?
      before_create   :create_remote_resource,  :unless => :nosync?
      before_destroy  :destroy_remote_resource, :unless => :nosync?
      
      before_validation :reset_expiration_date, :on => :create, :unless => :nosync?
      
      validates_presence_of :expires_at
      
      default_remote_attributes = column_names - %w{id created_at updated_at expires_at}
      @remote_attribute_map = default_remote_attributes.map_to_self
      @remote_attribute_routes = {}
      @expires_after = 1.day
      
      extend_remote_model
    end
    
    
    
    module ClassMethods
      
      def remote_key(*args)
        if args.any?
          remote_key = args.first
          raise("#{remote_key} is not the name of a remote attribute") unless remote_attribute_names.member?(remote_key)
          @remote_key = remote_key
          fetch_with(remote_key)
          remote_key
        else
          @remote_key || generate_default_remote_key
        end
      end
      
      def expires_after(*args)
        if args.any?
          @expires_after = args.first
        else
          @expires_after
        end
      end
      
      def attr_remote(*attrs)
        map = attrs.extract_options!
        map = attrs.map_to_self.merge(map)
        @remote_attribute_map = map
        
        @remote_attribute_routes = {}
        fetch_with(*local_attribute_names)
      end
      
      def fetch_with(*local_keys)
        remote_keys_and_routes = extract_remote_keys_and_routes(*local_keys)
        @remote_attribute_routes.merge!(remote_keys_and_routes)
      end
      alias :find_by :fetch_with
      
      
      
      attr_reader :remote_attribute_map,
                  :remote_attribute_routes
      
      def local_key
        local_attribute_name(remote_key)
      end
      
      def remote_attribute_names
        remote_attribute_map.keys
      end
      
      def local_attribute_names
        remote_attribute_map.values
      end
      
      def remote_attribute_name(local_attr)
        remote_attribute_map.key(local_attr) || local_attr
      end
      
      def local_attribute_name(remote_attr)
        remote_attribute_map[remote_attr] || remote_attr
      end
      
      def route_for(local_key)
        remote_key = remote_attribute_name(local_key)
        remote_attribute_routes[remote_key] || default_route_for(local_key, remote_key)
      end
      
      def default_route_for(local_key, remote_key=nil)
        remote_key ||= remote_attribute_name(local_key)
        if remote_key.to_s == primary_key
          ":#{local_key}"
        else
          "by_#{remote_key}/:#{local_key}"
        end
      end
      
      
      
      # !nb: this method is called when associations are loaded
      # so you can use the remoted record in associations.
      def instantiate(*args)
        record = super
        record.pull_remote_data! if record.expired?
        record = nil if record.destroyed?
        record
      end
      
      
      
      def method_missing(method_sym, *args, &block)
        method_name = method_sym.to_s
        
        if method_name =~ /find_by_(.*)(!?)/
          local_attr, bang, value = $1.to_sym, !$2.blank?, args.first
          remote_attr = remote_attribute_name(local_attr)
          
          remote_key # Make sure we've figured out the remote
                     # primary key if we're evaluating a finder
          
          if remote_attribute_routes.key?(remote_attr)
            local_resource = where(local_attr => value).first ||
                             fetch_by(remote_attr, value)
            <commit_msg>check the global nosync before refreshing a record on instantiate.<commit_after>require "remotable/core_ext"
require "active_support/concern"


module Remotable
  module ActiveRecordExtender
    extend ActiveSupport::Concern
    
    
    
    included do
      before_update   :update_remote_resource,  :unless => :nosync?
      before_create   :create_remote_resource,  :unless => :nosync?
      before_destroy  :destroy_remote_resource, :unless => :nosync?
      
      before_validation :reset_expiration_date, :on => :create, :unless => :nosync?
      
      validates_presence_of :expires_at
      
      default_remote_attributes = column_names - %w{id created_at updated_at expires_at}
      @remote_attribute_map = default_remote_attributes.map_to_self
      @remote_attribute_routes = {}
      @expires_after = 1.day
      
      extend_remote_model
    end
    
    
    
    module ClassMethods
      
      def remote_key(*args)
        if args.any?
          remote_key = args.first
          raise("#{remote_key} is not the name of a remote attribute") unless remote_attribute_names.member?(remote_key)
          @remote_key = remote_key
          fetch_with(remote_key)
          remote_key
        else
          @remote_key || generate_default_remote_key
        end
      end
      
      def expires_after(*args)
        if args.any?
          @expires_after = args.first
        else
          @expires_after
        end
      end
      
      def attr_remote(*attrs)
        map = attrs.extract_options!
        map = attrs.map_to_self.merge(map)
        @remote_attribute_map = map
        
        @remote_attribute_routes = {}
        fetch_with(*local_attribute_names)
      end
      
      def fetch_with(*local_keys)
        remote_keys_and_routes = extract_remote_keys_and_routes(*local_keys)
        @remote_attribute_routes.merge!(remote_keys_and_routes)
      end
      alias :find_by :fetch_with
      
      
      
      attr_reader :remote_attribute_map,
                  :remote_attribute_routes
      
      def local_key
        local_attribute_name(remote_key)
      end
      
      def remote_attribute_names
        remote_attribute_map.keys
      end
      
      def local_attribute_names
        remote_attribute_map.values
      end
      
      def remote_attribute_name(local_attr)
        remote_attribute_map.key(local_attr) || local_attr
      end
      
      def local_attribute_name(remote_attr)
        remote_attribute_map[remote_attr] || remote_attr
      end
      
      def route_for(local_key)
        remote_key = remote_attribute_name(local_key)
        remote_attribute_routes[remote_key] || default_route_for(local_key, remote_key)
      end
      
      def default_route_for(local_key, remote_key=nil)
        remote_key ||= remote_attribute_name(local_key)
        if remote_key.to_s == primary_key
          ":#{local_key}"
        else
          "by_#{remote_key}/:#{local_key}"
        end
      end
      
      
      
      # !nb: this method is called when associations are loaded
      # so you can use the remoted record in associations.
      def instantiate(*args)
        record = super
        if record.expired? && !Remotable.nosync?
          record.pull_remote_data!
          record = nil if record.destroyed?
        end
        record
      end
      
      
      
      def method_missing(method_sym, *args, &block)
        method_name = method_sym.to_s
        
        if method_name =~ /find_by_(.*)(!?)/
          local_attr, bang, value = $1.to_sym, !$2.blank?, args.first
          remote_attr = remote_attribute_name(local_attr)
          
          remote_key # Make sure we've figured out the remote
                     # primary key if we're evaluating a finder
          
          if remote_attribute_routes.key?(remote_attr)
            local_resource = where(local_attr => value).first ||
                             fetch_by(remote_attr, value)
            
{'fraction_non_alphanumeric': 0.06664113366526235, 'fraction_numerical': 0.0007659900421294523, 'mean_word_length': 2.061352090660414, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 15, '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': '808861', 'n_tokens_mistral': 2286, 'n_tokens_neox': 2279, 'n_words': 449}