How do I get ActiveRecord to show the next id (last + 1) in Ruby on Rails?

Is there a compact way with ActiveRecord to query for what id it's going to use next if an object was going to be persisted to the database? In SQL, a query like this would look something like:

SELECT max(id) + 1 FROM some_table;

Solution 1:

Here is slightly modified Taryn East's version:

Model.maximum(:id).next

Solution 2:

While accepting fig's answer I might want to draw your attention to a small thing. If you are getting the next ID to set to a particular record before saving, I think its not a good idea.

because as an example in a web based system

  1. you get the last id as 10
  2. you set the next id as 11
  3. before you save the record someone else has saved the record, now the last id should be 12 likewise..

I'm not sure you want the last id to do what I'm thinking here, But if so this is just to draw your attention.

Solution 3:

If your database is Postgres, you can get the next id with this (example for a table called 'users'):

ActiveRecord::Base.connection.execute("select last_value from users_id_seq").first["last_value"]

Unlike the other answers, this value is not affected by the deletion of records.

There's probably a mySQL equivalent, but I don't have one set up to confirm.

If you have imported data into your postgresql database, there's a good chance that the next id value after the import is not set to the next integer greater than the largest one you imported. So you will run into problems trying to save the activerecord model instances.

In this scenario, you will need to set the next id value manually like this:

ActiveRecord::Base.connection.execute("alter sequence users_id_seq restart with 54321;") #or whatever value you need

Solution 4:

Slightly better than the accepted answer:

YourModel.maximum(:id) + 1

Still prone to race-conditions etc, but at least it will take note of skipped ids and is slightly more efficient than, say, ordering the table by id then returning the last.

Solution 5:

This is an old question, but none of the other answers work if you have deleted the last record:

Model.last.id #=> 10
Model.last.destroy
Model.last.id #=> 9, so (Model.last.id + 1) would be 10... but...
Model.create  #=> 11, your next id was actually 11

I solved the problem using the following approach:

current_value = ActiveRecord::Base.connection.execute("SELECT currval('models_id_seq')").first['currval'].to_i
Model.last.id #=> 10
Model.last.destroy
Model.last.id #=> 9
current_value + 1 #=> 11