Migrations are cancelled and duplicate column error - ruby-on-rails

When I write rails db:migrate, I get this error:
bundle exec rake db:migrate
== 20161209073230 AddActivationToUsers: migrating =============================
-- add_column(:users, :activation_digest, :string) rake aborted! StandardError: An error has occurred, this and all later migrations
canceled:
SQLite3::SQLException: duplicate column name: activation_digest: ALTER
TABLE "users" ADD "activation_digest" varchar
Here's my user table:
create_users.rb
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps null: false
end
end
end
This is my add_activation_to_users.rb:
class AddActivationToUsers < ActiveRecord::Migration
def change
add_column :users, :activation_digest, :string
add_column :users, :activated, :boolean, default: false
add_column :users, :activated_at, :datetime
end
end

SQLite3::SQLException: duplicate column name: activation_digest: ALTER TABLE "users" ADD "activation_digest" varchar
As the exception suggests, you have already added activation_digest in your users table.
You can check the columns of your users table right from the rails console with User.column_names.

You are already having activation_digest in your user table.
Please check your schema.rb. If you trying to add new column then you need to deleted already existing one.

Related

Migration failed after changing User ID to UUID

I changed my user id to UUID and modified a few tables related to user_id. However for some table like stream, I get the following error. Does anyone knows how to go around please?
-- change_column(:streams, :user_id, :string)
(18.1ms) ALTER TABLE "streams" ALTER COLUMN "user_id" TYPE character varying
(1.0ms) ROLLBACK
(1.3ms) SELECT pg_advisory_unlock(740533580701532625)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::DatatypeMismatch: ERROR: foreign key constraint "fk_rails_bb64178f90" cannot be implemented
DETAIL: Key columns "user_id" and "id" are of incompatible types: character varying and bigint.
: ALTER TABLE "streams" ALTER COLUMN "user_id" TYPE character varying
The following steps helped fixing the issue:
class ConvertTableWithUserToString < ActiveRecord::Migration[5.1]
def change
add_column :users, :uuid, :uuid, default: "gen_random_uuid()", null: false
remove_foreign_key :streams, column: :user_id
change_table :users do |t|
t.remove :id
t.rename :uuid, :id
end
execute "ALTER TABLE users ADD PRIMARY KEY (id);"
change_column :streams, :user_id, :string
end
end

Relation does not exist issue

I am running into an issue when migrating the db
class CreateBlogoTaggings < ActiveRecord::Migration
def change
taggings_table = "#{Blogo.table_name_prefix}taggings"
create_table(taggings_table) do |t|
t.integer :post_id, null: false
t.integer :tag_id , null: false
end
add_index taggings_table, :tag_id, unique: true
add_index taggings_table, :post_id, unique: true
if defined?(Foreigner)
tags_table = "#{Blogo.table_name_prefix}tags"
posts_table = "#{Blogo.table_name_prefix}posts"
add_foreign_key taggings_table, tags_table , column: :tag_id
add_foreign_key taggings_table, posts_table, column: :post_id
end
end
end
Migrating that gives me
== 20180215114117 CreateBlogoTaggings: migrating ==============================
-- create_table("blogo_taggings")
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "posts" does not exist
: CREATE TABLE "blogo_taggings" ("id" serial primary key, "post_id" integer NOT NULL, CONSTRAINT fk_blogo_taggings_post_id FOREIGN KEY ("tpost_id") REFERENCES "posts" ("id"))
I have even commented everything inside change below the create_table method and it still gives the same error.
Can you tell me why this is happening?
It is expecting a posts table probably backed by a Post model. Try editing the CreateBlogoTaggings migration file. Replace all occurrences of post_id with blogo_post_id and run the migration again.

Can't migrate to heroku (Ruby on Rails tutorial [Michael Hartl] chaper 10)

I am working through chapter 10 of the Hartl book. In the conclusion of this chapter, we reset the heroku database and then migrate. However when I run:
heroku run rails db:migrate
I get an error:
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedColumn: ERROR: column "password_digest_string" of relation "users" does not exist
: ALTER TABLE "users" DROP "password_digest_string"
Earlier in the tutorial, I removed a column called password_digest_string because it was named incorrectly and I didn't need it yet. It seems like rails is trying to delete the column again even though it isn't there anymore. I deleted the migration file that removed this column but it still is trying to drop it. What's also odd is that I've migrated the database several times since dropping that column and never had this issue until I reset it. Any suggestions?
EDIT:
here is my schema file:
ActiveRecord::Schema.define(version: 20170121224748) do
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "remember_digest"
t.boolean "admin", default: false
t.index ["email"], name: "index_users_on_email", unique: true
end
end
EDIT:
And my migrations in time-stamp order.
..._create_users.rb
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
..._add_index_to_users_email.rb
class AddIndexToUsersEmail < ActiveRecord::Migration[5.0]
def change
add_index :users, :email, unique: true
end
end
..._add_password_digest_to_users.rb
class AddPasswordDigestToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :password_digest, :string
end
end
..._remove_columns.rb
class RemoveColumns < ActiveRecord::Migration[5.0]
def self.up
remove_column :users, :password_digest_string
end
end
..._add_remember_digest_to_users.rb
class AddRememberDigestToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :remember_digest, :string
end
end
..._add_admin_to_users.rb
class AddAdminToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :admin, :boolean, default: false
end
end
It looks to me that the AddPasswordDigestToUsers migration initially looked like this (probably you misspelled):
class AddPasswordDigestToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :password_digest_string
end
end
Then you realized the column should be just password_digest. So you manually edited the migration file to what it looks now, rolled back, created the next migration which is RemoveColumns and then ran migration.
Now when you the migrations from the beginning, there will be no error if you are using sqlite3 (which is what you use for dev environment) due to the way column removal is handled in sqlite. But there will be an error if you use Postgres.
What you should have done
Instead of what you did, you should have just created a migration to change the column name, like this:
class RenamePasswordDigestStringColumn < ActiveRecord::Migration[5.0]
def self.up
rename_column :users, :password_digest_string, :password_string
end
end
What you can do now
To get past the problem without doing many changes now, you can just delete the RemoveColumns migration (and commit, push... etc that). That would be OK and I don't think it will harm your production or development environments.
$> heroku pg:reset DATABASE will make the db:migrate on heroku clean again

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

rake db:migrate works locally in sqlite3 but does not work in postgresql in heroku.
ERROR
PG::UndefinedTable: ERROR: relation "musicians" does not exist
: ALTER TABLE "orders" ADD CONSTRAINT "fk_rails_ad134589be"
FOREIGN KEY ("musician_id")
REFERENCES "musicians" ("id")
(0.9ms) ROLLBACK
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "musicians" does not exist
: ALTER TABLE "orders" ADD CONSTRAINT "fk_rails_ad134589be"
FOREIGN KEY ("musician_id")
Here is a link to the entire log: https://gist.github.com/helloravi/2cb69e0927e63e186b09
The following is the migration which does not get executed. The error is displayed below the migration code
class CreateAlbums < ActiveRecord::Migration
def change
create_table :albums do |t|
t.string :album_name
t.references :musician, index: true, foreign_key: true
t.timestamps null: false
end
add_foreign_key :albums, :users, column: :musician_id
end
end
I have a users table with a musician column which is boolean(some users are musicians)
I even tried using add_foreign_key and still I am not able to figure out what the problem is.
I tried rake db:schema:load and it worked. I want to be able to make rake db:migrate work because I need to be able to migrate in production.
SQLite does not check foreign keys, it simply ignores them. But PostgreSQL is very strict and raises an error when the foreign key constraint is not valid.
Rails foreign_key does not support what you want it to do. When you write t.references :musician then there must be a musicians table. But you want the foreign key to point to a users table.
I see two options:
Use t.references :users and rename that association in your albums.rb like this:
belongs_to :musician, class_name: 'User', foreign_key: 'user_id'
Or: you just use t.integer :musician_id instead of references and define the foreign key constraint manually with an execute 'ALTER TABLE ...'
What #spickermann said is correct.
Changing your migration to the following should work:
class CreateAlbums < ActiveRecord::Migration
def change
create_table :albums do |t|
t.string :album_name
t.integer :musician_id
t.timestamps null: false
end
add_foreign_key :albums, :users, column: :musician_id
add_index :albums, :musician_id
end
end

Error adding foreign_key

My environemnt:
Ruby 2.2.1
Rails 4.2.4
mysql2 0.3.18 gem
Rails 4.2 introduced add_foreign_key. I am trying to use it so when a search_operation is deleted, the countries that belong to it are deleted from the countries table.
In my models/country.rb, I have:
class Country < ActiveRecord::Base
belongs_to :search_operation
end
In my models/search_operation.rb, I have:
class SearchOperation < ActiveRecord::Base
has_many :countries
end
In my create_countries migration, I have:
class CreateCountries < ActiveRecord::Migration
def change
create_table :countries do |t|
t.string :abbreviation
t.string :status
t.integer :search_operation_id
t.timestamps null: false
end
add_foreign_key :countries, :search_operations, on_delete: :cascade
end
end
In my search_operations migration, I have:
class CreateSearchOperations < ActiveRecord::Migration
def change
create_table :search_operations do |t|
t.string :text
t.string :status
t.timestamps null: false
end
end
end
When I run rake db:migrate, here's what I get:
== 20151010195957 CreateCountries: migrating ==================================
-- create_table(:countries)
-> 0.0064s
-- add_foreign_key(:countries, :search_operations, {:on_delete=>:cascade})
rake aborted!
StandardError: An error has occurred, all later migrations canceled:
Mysql2::Error: Can't create table 'tracker.#sql-463_8f' (errno: 150): ALTER TABLE `countries` ADD CONSTRAINT `fk_rails_c9a545f88d`
FOREIGN KEY (`search_operation_id`)
REFERENCES `search_operations` (`id`)
ON DELETE CASCADE/home/trackur/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:305:in `query'
I believe I am using the proper syntax here. Any ideas?
Solution:
Make sure the migration order is: create search_operations table first, followed by other tables that use its id as a foreign key. I guess ActiveRecord is going to follow the chronological order of when the migration files were created.
Make sure you create the search_operations table before the countries table.
If you set a foreign key the referenced table has to exist.

Resources