Sha256: 1c7c483802a94fb10c2b7fb02c0ecb641cf7eab18380e25ff335609eab446dad

Contents?: true

Size: 1.81 KB

Versions: 2

Compression:

Stored size: 1.81 KB

Contents

# = Archon.insert_into_select
module Archon
  def self.insert_into_select(insertion_table, selection, options = {})
    return InsertIntoSelect.new insertion_table, selection, options
  end

  # = InsertIntoSelect
  #
  # Extends an ARel InsertManager that will generate an `INSERT INTO (...) SELECT` query, which will
  # insert data into the given table from the given selection - either an ARel SelectManager-ish, or
  # an ActiveRecord::Relation.
  #
  # It will try to determine the columns that will be inserted from the projections specified in the
  # given selection.
  class InsertIntoSelect < Arel::InsertManager
    attr_reader :projections
    def initialize(tableish, selectish, options = {})
      super()
      self.into tableish.respond_to?(:arel_table) ? tableish.arel_table : tableish
      self.select selectish.respond_to?(:arel) ? selectish.arel : selectish

      # Fetch the insert columns from the options - default to the select column names interpolated
      # into the inserted table:
      self.columns.concat options.fetch(
        :columns,
        ast.select.projections.map do |projection|
          column_name = case projection
                        when Arel::Attributes::Attribute
                          projection.name
                        when Arel::Nodes::As
                          projection.right.delete('"').to_sym
                        when Arel::Nodes::NamedFunction
                          projection.alias.delete('"').to_sym
                        when String
                          _table, name = projection.split('.') if projection['.']
                          (name || projection).delete('"').to_sym
                        else
                          raise "Don't know how to..."
                        end
          ast.relation[column_name]
        end
      )
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
archon-0.0.5 lib/archon/insert_into_select.rb
archon-0.0.4 lib/archon/insert_into_select.rb