fakes associations like much like ActiveRecord according to the cached OpenERP data model
544755
def relationnal_result(method_name, *arguments)
      self.class.reload_fields_definition(false)
      if self.class.many2one_associations.has_key?(method_name)
        load_m2o_association(method_name, *arguments)
      elsif self.class.polymorphic_m2o_associations.has_key?(method_name)# && @associations[method_name]
        load_polymorphic_m2o_association(method_name, *arguments)
#        values = @associations[method_name].split(',')
#        self.class.const_get(values[0]).find(values[1], arguments.extract_options!)
      else # o2m or m2m
        load_x2m_association(method_name, *arguments)
      end
    end
723834
def hack_for_has_many_counter_cache(parent_record, column, value)
      association = parent_record.association(column.name)
      counter_attr = association.send(:cached_counter_attribute_name)
      difference = value.select(&:persisted?).size - parent_record.send(counter_attr)

      if parent_record.new_record?
        parent_record.send "#{column.name}=", value
        parent_record.send "#{counter_attr}_will_change!"
      else
        # don't decrement counter for deleted records, on destroy they will update counter
        difference += (parent_record.send(column.name) - value).size
        association.send :update_counter, difference unless difference.zero?
      end

      # update counters on old parents if belongs_to is changed
      value.select(&:persisted?).each do |record|
        key = record.send(column.association.foreign_key)
        parent_record.class.decrement_counter counter_attr, key if key && key != parent_record.id # rubocop:disable Rails/SkipsModelValidations
      end
      parent_record.send "#{column.name}=", value if parent_record.persisted?
    end
222958
def assert_concrete_activerecord_class(class_name)
      if class_name.constantize.abstract_class?
        raise format(::PaperTrail::ModelConfig::E_HPT_ABSTRACT_CLASS, @model_class, class_name)
      end
    end
286364
def find_polymorphic_association(links, method)
      links.select { |_, data| data.is_a?(Hash) }
        .find { |assoc, _| assoc.to_s.downcase == method.to_s.downcase }
    end
359606
def restore_record(record, attributes)
      primary_key = record.class.primary_key
      primary_key = [primary_key].compact unless primary_key.is_a?(Array)
      primary_key.each do |key|
        record.send("#{key.to_s}=", attributes[key.to_s])
      end

      attrs, association_attrs = attributes_and_associations(record.class, attributes)
      attrs.each_pair do |key, value|
        begin
          record.send("#{key}=", value)
        rescue
          record.errors.add(key.to_sym, "could not be restored to #{value.inspect}")
        end
      end

      association_attrs.each_pair do |key, values|
        restore_association(record, key, values) if values
      end
      
      # Check if the record already exists in the database and restore its state.
      # This must be done last because otherwise associations on an existing record
      # can be deleted when a revision is restored to memory.
      exists = record.class.find(record.send(record.class.primary_key)) rescue nil
      if exists
        record.instance_variable_set(:@new_record, nil) if record.instance_variable_defined?(:@new_record)
        # ActiveRecord 3.0.2 and 3.0.3 used @persisted instead of @new_record
        record.instance_variable_set(:@persisted, true) if record.instance_variable_defined?(:@persisted)
      end
    end
331277
def record_from_current_or_find(klass, id, current)
      if current.is_a?(ActiveRecord::Base) && current.id.to_s == id
        # modifying the current object of a singular association
        current
      elsif current.respond_to?(:any?) && current.any? { |o| o.id.to_s == id }
        # modifying one of the current objects in a plural association
        current.detect { |o| o.id.to_s == id }
      else # attaching an existing but not-current object
        klass.find(id)
      end
    end
1215140
def table_rows
      now = ActiveRecord::Base.default_timezone == :utc ? Time.now.utc : Time.now
      now = now.to_s(:db)

      # allow a standard key to be used for doing defaults in YAML
      fixtures.delete('DEFAULTS')

      # track any join tables we need to insert later
      rows = Hash.new { |h,table| h[table] = [] }

      rows[table_name] = fixtures.map do |label, fixture|
        row = fixture.to_hash

        if model_class && model_class < ActiveRecord::Base
          # fill in timestamp columns if they aren't specified and the model is set to record_timestamps
          if model_class.record_timestamps
            timestamp_column_names.each do |name|
              row[name] = now unless row.key?(name)
            end
          end

          # interpolate the fixture label
          row.each do |key, value|
            row[key] = label if value == "$LABEL"
          end

          # generate a primary key if necessary
          if has_primary_key_column? && !row.include?(primary_key_name)
            row[primary_key_name] = ActiveRecord::Fixtures.identify(label)
          end

          # If STI is used, find the correct subclass for association reflection
          reflection_class =
            if row.include?(inheritance_column_name)
              row[inheritance_column_name].constantize rescue model_class
            else
              model_class
            end

          reflection_class.reflect_on_all_associations.each do |association|
            case association.macro
            when :belongs_to
              # Do not replace association name with association foreign key if they are named the same
              fk_name = (association.options[:foreign_key] || "#{association.name}_id").to_s

              if association.name.to_s != fk_name && value = row.delete(association.name.to_s)
                if association.options[:polymorphic] && value.sub!(/\s*\(([^\)]*)\)\s*$/, "")
                  # support polymorphic belongs_to as "label (Type)"
                  row[association.foreign_type] = $1
                end

                row[fk_name] = ActiveRecord::Fixtures.identify(value)
              end
            when :has_and_belongs_to_many
              if (targets = row.delete(association.name.to_s))
                targets = targets.is_a?(Array) ? targets : targets.split(/\s*,\s*/)
                table_name = association.options[:join_table]
                rows[table_name].concat targets.map { |target|
                  { association.foreign_key             => row[primary_key_name],
                    association.association_foreign_key => ActiveRecord::Fixtures.identify(target) }
                }
              end
            end
          end
        end

        row
      end
      rows
    end
587521
def associations_hash
      hash = {}
      @scope.associations.each do |association, options|
        hash.merge!(render_association(association, options))
      end
      hash
    end
365180
def revisionable_associations(options = acts_as_revisionable_options[:associations])
      return nil unless options
      options = [options] unless options.kind_of?(Array)
      associations = {}
      options.each do |association|
        if association.kind_of?(Symbol)
          associations[association] = true
        elsif association.kind_of?(Hash)
          association.each_pair do |key, value|
            associations[key] = revisionable_associations(value)
          end
        end
      end
      return associations
    end
1070167
def record_store(store)
      store = RecordCache::Base.stores[store] || ActiveSupport::Cache.lookup_store(store) if store.is_a?(Symbol)
      store ||= Rails.cache if defined?(::Rails)
      store ||= ActiveSupport::Cache.lookup_store(:memory_store)
      RecordCache::MultiRead.test(store)
    end
1092842
def association(name) #:nodoc:
      association = association_instance_get(name)

      if association.nil?
        reflection  = self.class.reflect_on_association(name)
        if reflection.options[:active_model]
          association = ActiveRecord::Associations::HasManyForActiveModelAssociation.new(self, reflection)
        else
          association = reflection.association_class.new(self, reflection)
        end
        association_instance_set(name, association)
      end

      association
    end
864170
def _cache_lazy_values
      action_links.each(&:name_to_cache) if cache_action_link_urls
      columns.select(&:sortable?).each(&:sort)
      columns.select(&:searchable?).each(&:search_sql)
      actions.each do |action_name|
        action = send(action_name)
        Array(action.class.columns_collections).each { |method| action.send(method) }
      end
    end
146648
def associated_records_to_validate_or_save(association,
                                               new_record,
                                               autosave)
      if new_record || autosave
        association && association.target
      else
        association.target.find_all(&:new_record?)
      end
    end
5735
def ensure_valid_associated_record(association)
      value = send(association)
      predicate = :"#{association}?"

      if !value.class.respond_to?(predicate) || !value.class.send(predicate)
        errors.add association, I18n.t(:invalid, scope: [:errors, :messages])
      end
    end
927496
static QueryMeta buildUpdateSql(ActiveRecord activeRecord) {
        QueryMeta     queryMeta = new QueryMeta();
        String        sql;
        String        tableName = activeRecord.getTableName();
        StringBuilder sb        = new StringBuilder("UPDATE ");
        sb.append(tableName);
        sb.append(" SET ");

        final int[]  pos  = {1};
        List<Object> list = parseSet(activeRecord, pos, sb);

        sb.append(Const.SQL_WHERE).append(Const.SPACE);
        activeRecord.whereValues.forEach(where -> {
            if ("IS".equals(where.getOpt())) {
                sb.append(where.getKey()).append(Const.SPACE)
                        .append(where.getValue()).append(Const.SPACE).append(Const.SQL_AND).append(Const.SPACE);
                list.add(where.getValue());
            } else {
                sb.append(where.getKey()).append(Const.SPACE)
                        .append(where.getOpt()).append(Const.SPACE)
                        .append(":p").append(pos[0]++).append(Const.SPACE).append(Const.SQL_AND).append(Const.SPACE);
                list.add(where.getValue());
            }
        });

        sql = sb.toString().replace(", " + Const.SQL_WHERE + Const.SPACE, Const.SPACE + Const.SQL_WHERE + Const.SPACE)
                .replace(Const.SQL_AND + Const.SPACE + Const.SQL_OR, Const.SQL_OR);
        if (sql.endsWith(Const.SQL_AND + Const.SPACE)) {
            sql = sql.substring(0, sql.length() - 5);
        }

        Object[] args = list.toArray();
        queryMeta.setParams(args);
        queryMeta.setSql(sql);
        return queryMeta;
    }
907451
def awesome_mongo_mapper_association(object)
      return object.inspect if !defined?(::ActiveSupport::OrderedHash)
      return awesome_object(object) if @options[:raw]

      association = object.class.name.split('::').last.titleize.downcase.sub(/ association$/, '')
      association = "embeds #{association}" if object.embeddable?
      class_name = object.class_name

      "#{colorize(association, :assoc)} #{colorize(class_name, :class)}"
    end
759835
def _association(args, default_options={})
      return if options.nil?

      options = args.first

      if options.is_a?(Hash)
        options     = {}.merge(options)
        name        = options.keys.first
        properties  = options.delete(name)

        @associations[name] = default_options.merge({ :include => properties }).merge(options)
      elsif options.is_a?(Array)
        options.each do |option|
          association option
        end
      else
        @associations[options] = args[1] || {}
      end
    end