rake db:migrate is not working - ruby-on-rails

I'm working through the rails tutorial and have gotten stuck. Starting at Listing 8.16 I have made the following modifications to <timestamp>_add_remember_token_to_users.rb:
class AddRememberTokenToUsers < ActiveRecord::Migration
def change
add_column :users, :remember_token, :string
add_index :users, :remember_token
end
end
The guide then says to update dev & test db as usual:
$ bundle exec rake db:migrate
$ bundle exec rake db:test:prepare
My User test for the *remember_token* is still failing so I took a look at the user table in dev and tests database with command line sqlite3. They look like this:
sqlite> .schema users
CREATE TABLE "users" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
"name" varchar(255),
"email" varchar(255),
"created_at" datetime NOT NULL,
"updated_at" datetime NOT NULL,
"password_digest" varchar(255));
CREATE UNIQUE INDEX "index_users_on_email" ON "users" ("email");
It seems like my migration has not been run yet but I do not know how to force it to run.

Try to rebuild your database structure(WARNING: all db-data will be lost):
rake db:drop:all
rake db:create:all
rake db:migrate
If you use Rails < 4.1, don't forget to prepare test database:
rake db:test:prepare
This is the easiest solution since you are working with tutorial. However in production or having important data in development you should take time to investigate the issue. In this case you most likely had created an empty migration, ran rake db:migrate, then added instructions to the migration, so you don't see a new field and further rake db:migrate does nothing. To resolve this issue you need to comment your change instructions, perform rake db:rollback, uncomment instructions and then rake db:migrate to apply instructions you missed.

I had the same issue as the initial question. $ bundle exec rake db:migrate wasn't adding remember_token to the .db and Latha Doddikadi's answer worked for me.
I did:
rake db:rollback
and then:
$ bundle exec rake db:migrate
which added the remember_token field to the database followed by:
bundle exec rspec spec/models/user_spec.rb
which passed.
Finished in 0.92841 seconds
21 examples, 0 failures

Roll back and then re run the migration it might work.
rake db:rollback
And after rolling back re run your migrations again.

I had a bizarre case of the last migration simply refusing to run. I'd created the migration file manually. So I deleted it and remade the migration using
rails g migration ...
and copied the code into the new file and it ran.
I didn't discover why manually creating that file didn't work; all I know is doing it the 'right/rails way' fixed the issue.
Leaving this here in case it helps someone else.

Related

Migration not executed from rspec

I created the following migration script (using bundle exec rails generate migration CreateSequenceStudentId):
class CreateSequenceStudentId < ActiveRecord::Migration[6.0]
def change
# Based on: https://schmijos.medium.com/execute-sql-in-rails-migrations-cdb26f51c683
execute 'CREATE SEQUENCE IF NOT EXISTS student_id;'
end
end
Then executed bundle exec rails db:migrate RAILS_ENV=test and it completed. I can access the sequence using psql student_test -c"select nextval('student_id')". Running psql student_test -c"select * from schema_migrations sm" lists 20201122013457 at the very last. No problems so far.
I then wrote the following spec to access the sequence:
sql = "select nextval('student_id')"
p Student.connection.select_all(sql)
And it failed:
# --- Caused by: ---
# PG::UndefinedTable:
# ERROR: relation "student_id" does not exist
# LINE 1: select nextval('student_id')
And I executed psql student_test -c"select nextval('student_id')" one more time and got:
ERROR: relation "student_id" does not exist
LINE 1: select nextval('student_id')
bundle exec rails db:migrate:status RAILS_ENV=test gives:
Status Migration ID Migration Name
--------------------------------------------------
...
up 20201122013457 Create sequence student
So it indicates the migration executed successfully.
psql student_test -c"select * from schema_migrations sm" gives:
version
----------------
20201122013457
20191209013052
20191220005953
20191225001051
20191225001255
20191225001458
...
The new script was executed first. This smells fishy.
Sounds like the migration ran successfully when using db:migrate but not when running rspec. Appreciate any pointers on what I could be doing wrong.
PS: Based on this solution, I have checked if the script name is unique and it is.
I was able to fix your issue by running exact below commands. I found the answer here.
RAILS_ENV=test rake db:drop
RAILS_ENV=test rake db:create
RAILS_ENV=test rake db:migrate
UPDATE:
I found also the way to fix rails db:reset command, you just need to add line config.active_record.schema_format = :sql in your application.rb so info about sequence will be stored in structure.sql. Please take a look that with default schema dump :ruby info about seqeunce is not stored in schema.rb file.
Important: make sure to firstly create structure.sql with rails db:migrate and then run rails db:reset. After just rails db:migrate I'm still getting the error you want to fix.

Migration with SQL sequence is not applied in test environment

I have the current migration
class CreateSlugSequence < ActiveRecord::Migration[5.2]
def up
execute <<-SQL
CREATE SEQUENCE slug_sequence
SQL
end
def down
execute <<-SQL
DROP SEQUENCE slug_sequence
SQL
end
end
I run rails db:migrate
Enter rails c (development mode)
Run ActiveRecord::Base.connection.exec_query("select nextval('slug_sequence')")[0]['nextval']
And get the expected value
But if I enter rails c in test mode, for some reason, the sequence table does not exist
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "slug_sequence" does not exist
I ran ActiveRecord::Migrator.current_version, to check what was the last migration applied and it returns the latest version.
Thanks for the help in advance.
I recommended dropping the test db and recreating it. Although these should remain in sync they sometimes do not and you have to do manual steps to get them together.
RAILS_ENV=test rake db:reset
Weird that it is not working with that, would be interesting to drop a pry debugger in that task and see what is going on. https://github.com/rails/rails/blob/master/activerecord/lib/active_record/railties/databases.rake#L122
Manual steps
RAILS_ENV=test rake db:drop
RAILS_ENV=test rake db:create
RAILS_ENV=test rake db:migrate
I found the way to fix rails db:reset command, you just need to add line config.active_record.schema_format = :sql in your application.rb so info about sequence will be stored in structure.sql. Please take a look that with default schema dump :ruby info about seqeunce is not stored in schema.rb file.
Important: make sure to firstly create structure.sql with rails db:migrate and then run rails db:reset. After just rails db:migrate I'm still getting the error you want to fix.

Migrations are pending. To resolve this issue, run: bin/rails db:migrate RAILS_ENV=development

I am rather new to Rails, and I am attempting to run an app from my console. When I open up the site, however, I see this error message. Does anyone have any insight on what it means?
When I try running "rails db:migrate RAILS_ENV=development" I just get:
Migrations are pending. To resolve this issue, run: bin/rails db:migrate RAILS_ENV=development
When I try running just "rails db:migrate" or "rake db:migrate" I get:
ArgumentError: wrong number of arguments (0 for 1)
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.1/lib/active_record/migration.rb:600:in `migrate'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.1/lib/active_record/migration.rb:573:in `check_pending!'
Thank you so much!
To resolve this issue, run: bin/rails rake db:migrate RAILS_ENV=development
And the issue was raised due to pending migrations, which are created migration files at /db/migrate directory by doing add/remove fields to the existing active record or relation(table) in database.
Migrations are stored as files in the db/migrate directory, one for each migration class. The name of the file is of the form YYYYMMDDHHMMSS_create_products.rb, that is to say a UTC timestamp identifying the migration followed by an underscore followed by the name of the migration. The name of the migration class (CamelCased version) should match the latter part of the file name. For example 20080906120000_create_products.rb should define class CreateProducts and 20080906120001_add_details_to_products.rb should define AddDetailsToProducts. Rails uses this timestamp to determine which migration should be run and in what order, so if you're copying a migration from another application or generate a file yourself, be aware of its position in the order.
Example:
$bin/rails generate migration AddPartNumberToProducts
This will create an empty but appropriately named migration:
class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
def change
end
end
If the migration name is of the form "AddXXXToYYY" or "RemoveXXXFromYYY" and is followed by a list of column names and types then a migration containing the appropriate add_column and remove_column statements will be created.
$ bin/rails generate migration AddPartNumberToProducts part_number:string
will generate
class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
def change
add_column :products, :part_number, :string
end
end
Referred at: http://guides.rubyonrails.org/active_record_migrations.html
Goto your app folder and run below mention command:
bin/rails db:migrate RAILS_ENV=development
I ran commands
# wait until this completes successfully before continuing
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart
and it solved the problem for me.

rake db:rollback not working?

I'm writing my first Rails app. I've run a few rails generate model ... and rake db:migrate commands, but I now want to change my data model and so need to undo a few migrations.
The docs say I can undo a migration with rake db:rollback, but this isn't working. When I run this in the console the computer thinks for a few seconds but doesn't make any changes to db/migrate/ or db/migrate/schema.rb. No output is printed to the console.
Is this behavior correct? Shouldn't db:rollback be changing my schema? If so, can anyone think why it might not be working?
I'm on Rails v. 3.2.6.
EDIT
At the moment rake db:migrate:status gives
database: db/development.sqlite3
Status Migration ID Migration Name
--------------------------------------------------
up 20120617191211 Create irs
up 20120701154357 Create paths
up 20120701154421 Create nodes
up 20120702151447 ********** NO FILE **********
down 20120702155140 Create venues
down 20120703233833 Remove path from venues
Solution (see my comment): run
rake db:migrate:status
and correct problems you find there. In this case (per #MarkThomas' followup), you might want to check all files you need are in place.
This is what worked for me. Combine the steps given in this answer and comment by dB.
run rake db:migrate:status
If you have a ****NO FILE**** entry, just note the version number as noFileVersion. Note the version of the entry just above no file entry(stable_version).
created a "dummy" file with name noFileVersion_create_nothing.rb, and body
class CreateNothing < ActiveRecord::Migration[6.0]
def change
end
end
run rake db:migrate VERSION=stable_version
remove the noFileVersion_create_nothing.rb manually.
run rake db:migrate.
run rake db:migrate:status again to check if No file entry has disappeared.
The following worked for me:
rake db:migrate:down VERSION=20190304092208
Version number can be obtained by the following command:
rake db:migrate:status
This was the last version number to rollback one last migration
NOTE: Use the suggestions with caution, it is very dangerous for non-dev environments.
If
rake db:migrate:status
gives you a migration that says
up 20120702151447 ********** NO FILE **********
Then the best thing to do would be to do a (note that the following command will drop the database):
rake db:reset
to redo all migrations. If the last migration is the one missing, then schema.rb will have the last migration that rake db:migrate will look for:
ActiveRecord::Schema.define(:version => 20120702151447) do
Change that number to the last one in your migrate folder.

Need help migrating database from development to test using Rails

Similar questions has been asked a lot. But, I think my situation is a bit different. I pulled a db from Heroku (I use sqlite3 in prod) to my local machine (uses PostgreSQL ). The prod db didn't have any data at that time.
After that time I haven't done any db migrations to test. Now I have a couple of fields in my dev db. However, when I go to test console to see what I have (referring a User table) User.count returns 0, but returns 2 users in dev.
So I did rake db:migrate RAILS_ENV=test there was neither an error message nor a success message. I thought it was success and checked the test db if it has those 2 users and still nothing. Then I tried bundle exec rake db:test:prepare. This was the output
**You have 4 pending migrations:
20120415210441 CreateUsers
20120418064930 AddIndexToUsersEmail
20120419034627 AddPasswordDigestToUsers
20120504031144 AddRememberTokenToUsers
Run `rake db:migrate` to update your database then try again.**
What is the solution?
EDIT:
FYI: I am using windows
I also run rake db:migrate and I got this error.
$ rake db:migrate
== CreateUsers: migrating ====================================================
-- create_table(:users)
rake aborted!
An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: table "users" already exists: CREATE TABLE "users" ("id"
INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "email" varcha
(255), "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
The error message indicates that your dev and test migrations are out of sync.
First run migrate on dev. This will update dev with all your recent migrations.
rake db:migrate
Then run db:test:prepare. This will make the test database the same schema as dev.
rake db:test:prepare
Now, understand that db:test:prepare makes test have the same schema as dev, but with no records. To populate records in test, implement fixtures or factories (see the factory-girl gem). Factories are generally called in your test to create records for that test.
That's another question and another answer.
You should drop the table and re-run the migrations.
If you don't know how to drop a table in SQLite, then
comment out the create_table method call in the 20120415210441_CreateUsers.rb.
Run > rake db:migrate VERSION=20120415210441
Run > rake db:migrate VERSION=??? where ??? is the version of the migration prior to CreateUsers.
Uncomment the code in 20120415210441_CreateUsers.rb
Run > rake db:migrate

Resources