Can't add foreign key on relation table - ruby-on-rails

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

Related

adding relation through migrations in Rails 5

I followed the advice of this SO post. An entree belongs_to a venue. So I expect a foreign key named venue_id on the entrees table. I generated the following:
rails g migration AddEntreeToVenue entree:belongs_to
It created the following migration:
class AddEntreeToVenue < ActiveRecord::Migration[5.0]
def change
add_reference :venues, :entree, foreign_key: true
end
end
But after running db:migrate, I look at the entrees table and no foreign key:
Indexes:
"entrees_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "venues" CONSTRAINT "fk_rails_0cf11999c6" FOREIGN KEY (entree_id) REFERENCES entrees(id)
What it appeared to do was add the foreign key to the venues table, not the entrees table. What did I do wrong?
Your generator command specified that Rails should create a belongs_to column on Venues. What you actually want is the opposite:
rails g migration AddVenueToEntrees venue:belongs_to
This will create a migration that modifies entrees, adding a venue_id column with a foreign key constraint on venues.id.

Foreign Key in Rails - Errors

I'm trying to add a new foreign key column to my Customers table. This is my migration:
class AddCompanyForeignKeyToCustomers < ActiveRecord::Migration[5.1]
def change
add_reference :customers, :company, foreign_key: true
add_foreign_key :customers, :companies
end
end
These are the errors I'm getting:
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::DuplicateObject: ERROR: constraint "fk_rails_ef51a916ef" for relation "customers" already exists
: ALTER TABLE "customers" ADD CONSTRAINT "fk_rails_ef51a916ef"
FOREIGN KEY ("company_id")
REFERENCES "companies" ("id")
ActiveRecord::StatementInvalid: PG::DuplicateObject: ERROR: constraint "fk_rails_ef51a916ef" for relation "customers" already exists
: ALTER TABLE "customers" ADD CONSTRAINT "fk_rails_ef51a916ef"
FOREIGN KEY ("company_id")
REFERENCES "companies" ("id")
PG::DuplicateObject: ERROR: constraint "fk_rails_ef51a916ef" for relation "customers" already exists
What does any of that mean? I don't know what fk_rails_$NUMBER is.
It means that you are trying to create a foreign key constraint that duplicates one you already have.
This line creates a foreign key constraint on customers referencing companies, as well as creates the company_id column
add_reference :customers, :company, foreign_key: true
This line is trying to do the foreign key constraint again
add_foreign_key :customers, :companies
Just remove one or the other, depending on whether or not you also need to add the company_id column
You're trying to add foreign keys twice by calling add_reference and add_foreign_key. The docs will tell you more, but basically add_foreign_key adds a key and add_reference can add a foreign key (which you are doing with foreign_key: true in your code above), so you should just use one or the other.
If I were you I would just use add_foreign_key, it seems more suited to what you're trying to do:
class AddCompanyForeignKeyToCustomers < ActiveRecord::Migration[5.1]
def change
add_foreign_key :customers, :companies
end
end

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`

Rails Postgres Schema references rollback issue

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.

How to get Rails to insert a Foreign key constraint in DB?

I have a ruby model called MyModelA and MyModelB as shown below
class MyModelA < ActiveRecord::Base
belongs_to :mymodelb
class MyModelB < ActiveRecord::Base
# Blah Blah Blah
When I create the database with rake db:create command, I notice that MYMODELA table doesn't have a foreign key constraint on it. I manually inserted it like this:
ALTER TABLE MYMODELA ADD FOREIGN KEY (MYMODELB_ID) REFERENCES MYMODELB(ID);
How can I define my model such that this DB foreign key constraint is automatically created without me having to manually add it later?
Rails doesn't provide a migration helper to add foreign_key. But you can use foreigner gem
You do do this to add a foreign_key using foreigner gem
create_table :products do |t|
t.string :name
t.integer :factory_id
t.foreign_key :factories
end
generate a migration:
rails g migration AddmymodelbidToMyModelA mymodelb_id:integer
go the the migration file and add
add_index :mymodela, :mymodelb_id
just between the two end clauses
run rake:db:migrate

Resources