Why does rails 5 add the nextval method to the schema file?

After upgrading to Rails 5, my schema file continues to change when db: migrate starts. Rails is changing:

create_table "flightlessons", force: :cascade do |t| 

in

 create_table "flightlessons", id: :integer, default: -> { "nextval('lessons_id_seq'::regclass)" }, force: :cascade do |t| 

This only happens on this model. Why do rails implement nextval on this particular model? And why does he mistakenly enter the model name (classes_id_seq should be flightlessons_id_seq). However, in manual mode, changing it to flightlessons_id_seq leads to the same error of lack of communication.

 PG::UndefinedTable: ERROR: relation "lessons_id_seq" does not exist 

To continue, I just modify the schema.rb file back to what this line should be. Then I can migrate or test: prepare or whatever, until the next time the rails change it before using the nextval method.

Thanks for any understanding of this.

+7
ruby-on-rails postgresql
source share
1 answer

This is a bit long answer, so I split it into sections. Buckle up!

My theory

I assume that your development database contains the lessons_id_seq sequence and that its definition of flightlessons.id depends on it (that is, exactly what Rails places in your schema file).

How and why? You probably renamed the lessons table to flightlessons at some point in the past, but this renaming did not change the sequence the table depended on - and since schema.rb records not the sequence, the lessons_id_seq sequence lessons_id_seq not copied to your test database, and therefore you get this error.

To test my theory, run rails db and try the following commands:

 \d lessons_id_seq 

This should return the definition of this sequence. Then try:

 \d flightlessons 

And look at the id column definition. I expect it to include DEFAULT nextval('lessons_id_seq') .

difficult

The easiest way to fix this is to switch to structure.sql instead of schema.rb (see docs ). This will keep the exact state of your database and avoid any interference or interpretation of Rails, which causes your current problem. I always recommend structure.sql for production systems.

However, you can also log into your development database and change the sequence name:

 ALTER SEQUENCE lessons_id_seq RENAME TO flightlessons_id_seq; ALTER TABLE flightlessons ALTER COLUMN id SET DEFAULT nextval('flightlessons_id_seq'); 

This would be a terrible idea on a production system, but if your problem is just local, it should fix the current state of the database with schema.rb and thus solve your current problem. You can program this for porting if you want rails db:drop db:create db:migrate work on a new application.

Why now?

The behavior in which Rails dumps the default value for your primary table primary key can be completely new in Rails 5. Previously, Rails may have simply trusted that your identifier column is at the normal default level and ignores any value that it actually saw. But I did not do research to make sure that this is true or not.

+15
source share

All Articles