From 89fc7fbf82c29463e20550cca3e10453614b61f8 Mon Sep 17 00:00:00 2001 From: Kasper Timm Hansen Date: Mon, 18 Mar 2019 22:17:06 +0100 Subject: Extract column check in values_list `values_list` is quite long and does far too many things. This also eagerly extract the keys in initialize instead of having to worry about calling them multiple times. --- activerecord/lib/active_record/insert_all.rb | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'activerecord/lib/active_record/insert_all.rb') diff --git a/activerecord/lib/active_record/insert_all.rb b/activerecord/lib/active_record/insert_all.rb index 3833cb2fcf..3d4749c34a 100644 --- a/activerecord/lib/active_record/insert_all.rb +++ b/activerecord/lib/active_record/insert_all.rb @@ -2,12 +2,14 @@ module ActiveRecord class InsertAll - attr_reader :model, :connection, :inserts, :on_duplicate, :returning, :unique_by + attr_reader :model, :connection, :inserts, :keys + attr_reader :on_duplicate, :returning, :unique_by def initialize(model, inserts, on_duplicate:, returning: nil, unique_by: nil) raise ArgumentError, "Empty list of attributes passed" if inserts.blank? - @model, @connection, @inserts, @on_duplicate, @returning, @unique_by = model, model.connection, inserts, on_duplicate, returning, unique_by + @model, @connection, @inserts, @keys = model, model.connection, inserts, inserts.first.keys.map(&:to_s).to_set + @on_duplicate, @returning, @unique_by = on_duplicate, returning, unique_by @returning = (connection.supports_insert_returning? ? primary_keys : false) if @returning.nil? @returning = false if @returning == [] @@ -21,10 +23,6 @@ module ActiveRecord connection.exec_query to_sql, "Bulk Insert" end - def keys - inserts.first.keys.map(&:to_s) - end - def updatable_columns keys - readonly_columns - unique_by_columns end @@ -92,14 +90,8 @@ module ActiveRecord def values_list columns = connection.schema_cache.columns_hash(model.table_name) - - column_names = columns.keys.to_set - keys = insert_all.keys.to_set - unknown_columns = keys - column_names - - unless unknown_columns.empty? - raise UnknownAttributeError.new(model.new, unknown_columns.first) - end + keys = insert_all.keys + verify_columns_exist_for(keys, columns) types = keys.map { |key| [ key, connection.lookup_cast_type_from_column(columns[key]) ] }.to_h @@ -145,6 +137,14 @@ module ActiveRecord columns.map(&connection.method(:quote_column_name)) end + def verify_columns_exist_for(keys, columns) + unknown_columns = keys - columns.keys + + if unknown_columns.any? + raise UnknownAttributeError.new(model.new, unknown_columns.first) + end + end + def conflict_columns @conflict_columns ||= begin conflict_columns = insert_all.unique_by.fetch(:columns) if insert_all.unique_by -- cgit v1.2.3