Rails Postgres Schema references rollback issue - ruby-on-rails

In my rails application I have multiple postgresql schemas.
SHOW search_path;
search_path
--------------
"$user",public,vehicle
I have two tables (dealers, inventories) in the vehicle schema. The relationship holds like this:
dealer has_many inventories
inventory belongs_to dealer
I created a migration to add the relationship as:
class AddDealerIdToVehicleInventories < ActiveRecord::Migration
def change
add_reference 'vehicle.inventories', :dealer, index: true, foreign_key: {on_delete: :cascade}
end
end
This migration works perfectly when I run: rake db:migrate, the foreign_key seems added to the table without any issue. But when I run rake db:rollback, I am getting this error message:
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedColumn: ERROR: column "vehicle.dealer_id" referenced in foreign key constraint does not exist
: ALTER TABLE "vehicle"."inventories" ADD CONSTRAINT "fk_rails_95ee16593d"
FOREIGN KEY ("vehicle.dealer_id")
REFERENCES "vehicle"."dealers" ("id")
ON DELETE CASCADE
I am not sure if I am making any mistakes or is the rails migration bug. Thanks for the help.

I solved the issue by making changes in the migration file as:
class AddDealerIdToVehicleInventories < ActiveRecord::Migration
def up
add_reference 'vehicle.inventories', :dealer, index: true, foreign_key: {on_delete: :cascade}
end
def down
execute <<-SQL
ALTER TABLE vehicle.inventories
DROP COLUMN dealer_id
SQL
end
end
Hope, this is useful for others too.

Related

PG::UndefinedTable: ERROR: relation "----' does not exist

I'm using SQlite for development environment and Postgre for Production.
At the development everything works nicely. But when I try to reset and to migrate the production Database I received the following message:
PG::UndefinedTable: ERROR: relation "priceranges" does not exist
...
FOREIGN KEY ("pricerange_id")
REFERENCES "priceranges" ("id")
My venue model:
belongs_to :pricerange, :class_name => "PriceRange"
My pricerange migration:
class CreatePriceRanges< ActiveRecord::Migration[5.0]
def change
create_table :price_ranges do |t|
t.string :price_description
t.timestamps
end
end
end
Any ideas?
The table name you are creating in your migration is price_ranges, not priceranges. Unless you are overriding the table name in the PriceRange model, your pricerange association on Venue will look for a foreign key named price_range_id, not pricerange_id. I would recommend sticking with convention, and making your association:
belongs_to :price_range # automatically uses class PriceRange, and foreign key `price_range_id`

Can't add foreign key on relation table

I have two models:
class BracketMatch < ActiveRecord::Base
belongs_to :match
belongs_to :bracket
end
and
class Bracket < ActiveRecord::Base
has_many :bracket_matches
# Has a STI column
end
I am trying to add a foreign key to the table bracket_matches.
add_foreign_key :bracket_matches, :brackets
Raises the following error
PG::ForeignKeyViolation: ERROR: insert or update on table "bracket_matches" violates foreign key constraint "fk_rails_39684e0d9b"
DETAIL: Key (bracket_id)=(122) is not present in table "brackets".
: ALTER TABLE "bracket_matches" ADD CONSTRAINT "fk_rails_39684e0d9b"
FOREIGN KEY ("bracket_id")
REFERENCES "brackets" ("id")
What am I doing wrong and why is it checking bracket_id on brackets instead of bracket_matches?
rails g migration AddFieldToBracketMatches bracket:references
Check your migration file and then rake db:migrate
Edit
In that case why not just rails g migration RemoveColumnFromBrackMatches , remove_column :bracket_matches, :bracket , rake db:migrate, then delete both those migration files and create the migration I suggested above
Add index:true like this
add_foreign_key :bracket_matches, :brackets ,index:true,foreign_key:true

Ruby on Rails does not generate foreign key from association

I have two set up two database tables called 'points' and 'activities'. I want to give the table 'points' a foreign key 'activity_id' by setting up the associations as follows:
class Activity < ActiveRecord::Base
belongs_to :user
has_many :points, dependent: :destroy
...
end
and
class Point < ActiveRecord::Base
belongs_to :activity
end
In addition, I have the following migrations file for creating the points table:
class CreatePoints < ActiveRecord::Migration
def change
create_table :points do |t|
t.integer :activity_id
t.timestamps null: false
t.boolean :activities_completed, array: true, default: []
t.integer :point_value
t.float :time_left
end
end
end
However, when I run
rake db:reset
rake db:migrate
rake db:seed
and then check the the table points by
rails c
Point.column_names
then the foreign key is missing:
irb(main):001:0> Point.column_names
=> ["id", "created_at", "updated_at", "activities_completed", "point_value", "time_left"]
What am I doing wrong? What can I do to make the foreign key activity_id a column of the points table?
I am new to Ruby and Rails. My Rails version is 4.24. Any help is appreciated.
Your create table migration should have a "t.belongs_to :activity, index: true" instead of creating the field activity_id with type integer.
You should have done something like this to add activity_id to your points table.
t.references :activity, index: true, foreign_key: true
#this would have created activity_id column in points
Since now, you have already created your migrations and ran rake db:migrate, learn to remove a column from a table. You need to write migrations to remove activity_id from your points table and add it again.
rails generate migration RemoveActivityIdFromPoints activity_id:integer
rails g migration AddActivityRefToPoints activity:references
These two should create proper migrations for you. Check your migrations folder for confirmation that everything went well, and run rake db:migrate and test again.
Follow this link to learn more about it. http://guides.rubyonrails.org/active_record_migrations.html
I discovered that there was a more fundamental problem. The migration script was not being executed during rake db:migrate. Therefore the changes I had made to the migration were ineffective. I therefore had to use
rake db:migrate:redo VERSION=20160605234351
When I ran this command, then the foreign key appeared.

Rails PostgreSQL migration giving error related to foreign keys [duplicate]

On migration I get the following error message:
PG::UndefinedTable: ERROR: relation "actioncodes" does not exist
: ALTER TABLE "organizations" ADD CONSTRAINT "fk_rails_4ecaa2493e"
FOREIGN KEY ("actioncode_id")
REFERENCES "actioncodes" ("id")
I have the following migration file for Organizations:
class CreateOrganizations < ActiveRecord::Migration
def change
create_table :organizations do |t|
t.string :name, null: false, limit: 40
t.references :actioncode, index: true, foreign_key: true
t.boolean :activated
t.datetime :activated_at
t.timestamps null: false
end
end
end
And for Actioncodes I have the migration file:
class CreateActioncodes < ActiveRecord::Migration
def change
create_table :actioncodes do |t|
t.string :code, null: false, limit: 20
t.string :description, limit: 255
t.timestamps null: false
end
end
end
class AddIndexToActioncodesCode < ActiveRecord::Migration
def change
add_index :actioncodes, :code, unique: true
end
end
The organization model file includes: belongs_to :actioncode.
While the actioncodes model file includes: has_many :organizations.
Any idea what could be causing the error message?
If I remove index: true, foreign_key: true from the migration file, it migrates without errors. And when I replace that line with the incorrect line t.references :actioncode_id, index: true, foreign_key: true, it gives the error below, where the last line ("ids") suggests Rails somehow seems to have problem with the name of the table?
PG::UndefinedTable: ERROR: relation "actioncode_ids" does not exist
: ALTER TABLE "organizations" ADD CONSTRAINT "fk_rails_604f95d1a1"
FOREIGN KEY ("actioncode_id_id")
REFERENCES "actioncode_ids" ("id")
So the issue is happening because CreateOrganizations migration is being run before CreateActioncodes is executed.
CreateActioncodes is to be run first thereby ensuring that the action codes table exists.
The order in which migrations are run is based on the time stamp of the migration - as indicated in the name of the file. 20141014183645_create_users.rb will run before 20141014205756_add_index_to_users_email.rb as the timestamp of the second one - 20141014205756 is after that of the first one - 20141014183645.
Make sure the time-stamps of the CreateOrganizations migration is after that of CreateActioncodes migration.
Either you could manually change the timestamp in the file names. Or delete these migration files, and create them in the correct order.
The foreign_key: true in this line:
t.references :actioncode, index: true, foreign_key: true
tells Rails to create a foreign key inside the database. A foreign key:
constraint specifies that the values in a column (or a group of columns) must match the values appearing in some row of another table. We say this maintains the referential integrity between two related tables.
So it is some logic inside the database (where it belongs) that ensures you can't put invalid values in your actioncode column and that you can't remove entries from the actioncodes table that are being used elsewhere.
In order to create the constraint, the referenced table (actioncodes) needs to exist before you refer to it. Looks like your migrations are trying to create organizations before actioncodes so all you need to do is rename the CreateOrganizations migration file so that its timestamp prefix comes after the one for CreateActioncodes. The prefix is just a timestamp in the format YYYYMMDDhhmmss so change the CreateOrganizations timestamp to the CreateActioncodes timestamp with one more second.
I was also getting this error. If you are using a test database to run rspec make sure you run rake db:test:prepare in the terminal before running rspec.
I had this same challenge when working on a Rails 6 application in Ubuntu 20.04.
I am working on a College Portal where I have model called School and another called Program. The model Program belongs to the model School, so it is required that I add a school references column to the programs table.
I used this command this create the migration file:
rails generate model School name:string logo:json motto:text address:text
rails generate model Program name:string logo:json motto:text school_id:references
However, when I run the command: rails db:migrate
I was getting the error:
== 20201208043945 CreateSchools: migrating ====================================
-- create_table(:schools)
-> 0.0140s
== 20201208043945 CreateSchools: migrated (0.0141s) ===========================
== 20201208043958 CreatePrograms: migrating ===================================
-- create_table(:programs)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "school_ids" does not exist
Here's how I solved it:
The issue was from the command:
rails generate model Program name:string logo:json motto:text school_id:references
It is supposed to be school:references and not school_id:references, so during the migration Rails is unable to find the table school_ids.
So I modified the command to:
rails generate model Program name:string logo:json motto:text school:references
And it worked fine.
That's all.
I hope this helps

I'm having trouble dropping a migration during a db:reset. Are my migrations incorrect?

I'm getting this error when I run a db:reset
rake aborted!
ActiveRecord::StatementInvalid: PG::DependentObjectsStillExist: ERROR: cannot drop table seasons because other objects depend on it
DETAIL: constraint weeks_season_id_fk on table weeks depends on table seasons
HINT: Use DROP ... CASCADE to drop the dependent objects too.
: DROP TABLE "seasons"
The most recent migrations I added were...
class AddSeasonIdToWeek < ActiveRecord::Migration
def change
add_column :weeks, :season_id, :integer, null: false, index: true
end
end
and
class AddForeignKeySeasonsToWeeks < ActiveRecord::Migration
def change
change_table :weeks do |a|
a.foreign_key :seasons
end
end
end
What do I need to do to get past this error?
Try using this in rails 4:
rake db:rollback
twice
In older versions of rails (probably 3 and before)
rake db:migrate:down
twice

Resources