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
Related
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
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.
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.
I was changing the name of my previous followers model. I decided to go back to it's original name but was having errors. I decided to use the Drop_table method to solve the issue but further issue pursist. I deleted any file related to followers and did rake db:schema:load which resulted in no errors. But whenever I try to do
rails g model Follower follower_id:integer followed_id:integer
and edit it to
def change
create_table :followers do |t|
t.integer :follower_id
t.integer :followed_id
t.timestamps
end
add_index :followers, :follower_id
add_index :followers, :leader_id
add_index :followers, [:follower_id, :leader_id], unique: true
end
Then I execute rake db:migrate and I get the following. Anyone has an idea how I'll be able to fix this issue without having to start from the beginning? any help is appreciated. Thank you.
== 20150910203914 CreateFollowers: migrating ==================================
-- create_table(:followers)
-> 0.0011s
-- add_index(:followers, :follower_id)
-> 0.0004s
-- add_index(:followers, :leader_id)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: table followers has no column named leader_id: CREATE INDEX "index_followers_on_leader_id" ON "followers" ("leader_id")/Users/Steven/.rvm/gems/ruby-2.1.3/gems/sqlite3-1.3.10/lib/sqlite3/database.rb:91:in `initialize'
As the error says, you don't have a column named leader_id. You should change your migration to:
def change
create_table :followers do |t|
t.integer :follower_id
t.integer :leader_id
t.timestamps
end
add_index :followers, :follower_id
add_index :followers, :leader_id
add_index :followers, [:follower_id, :leader_id], unique: true
end
or rather change leader_id by followed_id.
You should also check the references modifier in activerecord migrations (source).
Your table does not have a column leader_id. You can see that because you are creating the table in the migration, and only specifying 3 columns, not of which is leader_id. But you are trying to add an index using that column, which is what generates the error. If you don't want that column anymore, you need to change the index. If you do want it, then do as jihonora suggests.
Locally, my migrations are fine (although I'm using SQLite. Will switch to postgresql on development asap).
After resetting the database on Heroku with
heroku pg:reset DATABASE
I ran
heroku run rake db:migrate
But I am getting the following error after a migration:
== AddForeignKeysToCollaborations: migrating =================================
-- change_table(:collaborations)
rake aborted!
An error has occurred, this and all later migrations canceled:
PG::Error: ERROR: relation "member1_id" does not exist
: ALTER TABLE "collaborations" ADD CONSTRAINT "collaborations_member1_id_id_fk" FOREIGN KEY ("member1_id_id") REFERENCES "member1_id"(id) ON DELETE CASCADE
Here is that migration:
class AddForeignKeysToCollaborations < ActiveRecord::Migration
def change
change_table :collaborations do |t|
t.foreign_key :member1_id, dependent: :delete
t.foreign_key :member2_id, dependent: :delete
end
end
end
Previous migrations for Collaborations are
class CreateCollaborations < ActiveRecord::Migration
def change
create_table :collaborations do |t|
t.integer :user_id
t.integer :collaborator_id
t.timestamps
end
add_index :collaborations, :collaborator_id
add_index :collaborations, [:user_id, :collaborator_id], unique: true
end
end
and
class UpdateCollaborations < ActiveRecord::Migration
def change
change_table :collaborations do |t|
t.rename :user_id, :member1_id
t.rename :collaborator_id, :member2_id
t.string :status
end
add_index :collaborations,:member1_id
add_index :collaborations,:member2_id
end
end
Which are run in that order. Why is this error coming up on Heroku? Specifically, it looks like PG is adding an unnecessary "_id" to "member1_id"
You're calling foreigner's methods with the wrong arguments. The first argument is the referenced table name not the referencing column name. And since your column names don't nicely match the table names you'll need :column options as well. Something like this:
t.foreign_key :users, :column => :member1_id, :dependent => :delete
That assumes that :users is the table name that your :member1_id and :member2_id columns should be pointing at.
The error message:
relation "member1_id" does not exist
tells you that PostgreSQL is looking for a table called member1_id but can't find it.