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...
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