Typically, this is done by the database itself. Usually, the id
column of a table is an auto_increment
column which means that the database will keep an auto incrementing counter and assign its value to the new record when saved. Then, Rails has to pull the newly assigned id back from the database after inserting the record.
This is what Rails does when inserting a new row to DB (see docs for the insert
method):
# ActiveRecord::ConnectionAdapters::DatabaseStatements#insert
#
# Returns the last auto-generated ID from the affected table.
#
# +id_value+ will be returned unless the value is nil, in
# which case the database will attempt to calculate the last inserted
# id and return that value.
#
# If the next id was calculated in advance (as in Oracle), it should be
# passed in as +id_value+.
def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
sql, binds = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
value = exec_insert(sql, name, binds, pk, sequence_name)
id_value || last_inserted_id(value)
end
So, in practice, the ID is never passed from Rails in the INSERT statement. But after the insert, the created Rails object will have it's id
defined.