[ROR] ActiveRecord module - create on duplicate key update

Programming 2014.03.03 22:13

module ActiveRecord

  # = Active Record Persistence

  module Persistence

    extend ActiveSupport::Concern


    def create_on_duplicate_key_update!(keys)

      #keys = duplicate_keys.is_a? Array ? duplicate_keys : [duplicate_keys] 

      keys.collect! { |k| k.to_s }

      klass = self.class

      attributes_with_values = arel_attributes_with_values_for_create(attribute_names)

      column_hash = klass.connection.schema_cache.columns_hash klass.table_name

      db_columns_with_values = []

      attributes_with_values.map { |attr, value|

        real_column = column_hash[attr.name]

        db_columns_with_values << [real_column, value] if value.present?

        if (value.blank? && ['created_at', 'updated_at'].include?(real_column.name))

          now = DateTime.now

          db_columns_with_values << [real_column, now]

          self.send("#{attr.name}=",now)

        end

      }

      sql = "INSERT INTO #{self.class.quoted_table_name} (#{db_columns_with_values.collect{|c| klass.connection.quote_column_name(c.first.name)}.join(', ')})"

      sql << " VALUES (#{db_columns_with_values.collect{|c| klass.connection.quote(c.last)}.join(', ')}) "

      sql << " ON DUPLICATE KEY UPDATE "

      sql << sql_for_on_duplicate_key_update(keys,db_columns_with_values)


      klass.connection.execute sql

    end


    private

    def sql_for_on_duplicate_key_update(keys,db_columns_with_values)

      connection = self.class.connection

      results = []

      db_columns_with_values.map do |column, value|

        results << "#{self.class.quoted_table_name}.#{connection.quote_column_name(column.name)}=#{connection.quote(value, column)}" unless keys.include?(column.name)

      end

      results.join(',')

    end

  end

end



저작자 표시 비영리 변경 금지
신고


티스토리 툴바