Migration failed after changing User ID to UUID - ruby-on-rails

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

Related

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.

Migrations are cancelled and duplicate column error

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.

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.

How to remove the migration in my database?

I have been trying to use devise to make an authentication system for a blog that I am programming.When I try to view the blog, it says (Migrations are pending; run 'bin/rake db:migrate RAILS_ENV=development' to resolve this issue.), and when I run the command, it fails and renders this message:
Moussas-MacBook-Pro:theBlog moussasarr$ bin/rake db:migrate RAILS_ENV=development
== 20141031151735 SorceryCore: migrating ======================================
-- create_table(:authors)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: table "authors" already exists: CREATE TABLE "authors" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "username" varchar(255) NOT NULL, "email" varchar(255) NOT NULL, "crypted_password" varchar(255) NOT NULL, "salt" varchar(255) NOT NULL, "created_at" datetime, "updated_at" datetime) /Users/moussasarr/.rvm/gems/ruby-2.0.0-p576#railstutorial_rails_4_0/gems/sqlite3-1.3.8/lib/sqlite3/database.rb:91:in `initialize'
. I did migrate the authors table in the past but I had to restart from an earlier point as it was not working out. How can I delete the SorceryCore migration to make a new one ?
Here is the migration table:
class SorceryCore < ActiveRecord::Migration
def change
create_table :authors do |t|
t.string :username, :null => false
t.string :email, :null => false
t.string :crypted_password, :null => false
t.string :salt, :null => false
t.timestamps
end
add_index :authors, :email, unique: true
end
end
I really want to get this table out of the database and push in a new table.
Thanks a lot for your help ! This is the original problem that made me restart at an earlier level and made me lose so much time.
You can do db:migrate:down VERSION=your_migration_version to drop the table from the database, then delete the migration file and then run the migrations that devise needs for your authentication.
However, make sure that you don't need the authors table in any migrations until the devise one as it won't exist and can be a potentially big problem with your codebase and everything.

Resources