ruby-on-railsactiverecordruby-on-rails-7arel

How can I dump an ActiveModel record as an INSERT SQL statement?


Previously with Rails 6 I have been doing:

    # I have an existing record
    record = MyRandomModel.take

    # Now I wanna get the INSERT SQL which would have been generated and executed on the DB in case it was a new record....

    model = record.class
    values = record.send(:attributes_with_values, record.send(:attributes_for_create, model.column_names))

    substitutes_and_binds = model.send(:_substitute_values, values)

    insert_manager = model.arel_table.create_insert
    insert_manager.insert substitutes_and_binds

    sql = model.connection.unprepared_statement do
      model.connection.to_sql(insert_manager)
    end

    puts sql
    #=> "INSERT...."

However this procedure does not work in rails 7. It fails with the following error:

NoMethodError: undefined method `_substitute_values' for MyRandomModel:Class

UPDATE: I got this far:

  record = MyRandomModel.take
  model = record.class
  table = model.arel_table
  # Create an InsertManager object
  insert_manager = Arel::InsertManager.new(table)
  insert_manager.insert(
    record.send(:attributes_with_values, model.column_names).transform_keys { |name| table[name] }
  )
  insert_manager.to_sql

However it produces a prepared INSERT statement without the actual values...


Solution

  • Okay, I think I got it:

      record = MyRandomModel.take
      model = record.class
      table = model.arel_table
      # Create an InsertManager object
      insert_manager = Arel::InsertManager.new(table)
      insert_manager.insert(
        record.send(:attributes_with_values, model.column_names).transform_keys { |name| table[name] }
      )
      model.connection.unprepared_statement do
        model.connection.to_sql(insert_manager)
      end