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.
Related
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
I followed this guide on how to change the Primary Key:
http://www.lshift.net/blog/2013/09/30/changing-the-primary-key-type-in-ruby-on-rails-models/comment-page-1
Here is my code:
class Pk2 < ActiveRecord::Migration
def up
remove_column :contracts, :id # remove existing primary key
rename_column :contracts, :contractId, :id # rename existing UDID column
execute "ALTER TABLE contracts ADD PRIMARY KEY (id);"
end
def down
# Remove the UDID primary key. Note this would differ based on your database
execute "ALTER TABLE contracts DROP CONSTRAINT table_pkey;"
rename_column :contracts, :id, :contractId
add_column :contracts, :id, :primary_key
end
end
The error I keep getting is "Syntax around ALTER TABLE table ADD PRIMARY KEY"
Please help. Thank you.
The answer seemed to be that the OP separated the migration into 3 files:
1. Remove `:id` column
2. Rename `:contractId` column to `:id`
3. run `execute "ALTER TABLE contracts ADD PRIMARY KEY (id);"`
This allowed the OP to successfully run the migration
Some other resources:
Using Rails, how can I set my primary key to not be an integer-typed column?
Problems setting a custom primary key in a Rails 4 migration
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
Is there any difference between using t.references and executing SQL command to create foreign key relationship between products and category table as shown below? In other words, are the two different ways of doing the same thing or am I missing anything here?
class ExampleMigration < ActiveRecord::Migration
def up
create_table :products do |t|
t.references :category
end
#add a foreign key
execute <<-SQL
ALTER TABLE products
ADD CONSTRAINT fk_products_categories
FOREIGN KEY (category_id)
REFERENCES categories(id)
SQL
add_column :users, :home_page_url, :string
rename_column :users, :email, :email_address
end
def down
rename_column :users, :email_address, :email
remove_column :users, :home_page_url
execute <<-SQL
ALTER TABLE products
DROP FOREIGN KEY fk_products_categories
SQL
drop_table :products
end
end
They're not the same thing. Rails by default doesn't enforce foreign keys in the database. Instead, references when creating from the command line also creates a regular index, like this:
add_index :products, :category_id
Update:
Rails 5 actually does exactly the same thing now. So, to answer the original question: Nowadays, both are the same.
I found some thing intresting in this page.
http://railsforum.com/viewtopic.php?id=17318
From a comment :
Rails doesn't use foreign keys to perform his backend tasks. This
because some db like sqlite doesn't allow foreign keys on its tables.
So Rails doesn't provide an helper to build a foreign key
Also there is a gem foreigner for adding foreign keys to database table.
What creates the FOREIGN KEY constraint in Ruby on Rails 3?
I understand that by default the id field is created and also: PRIMARY KEY (id).
How about the foreign key ?
I have Shops and Products tables and the following associations:
Shop: has_many :products
Product: belongs_to :shop
In Product I have also:
t.integer "shop_id"
which is meant to be the foreign key, and also:
add_index("products", "shop_id")
However, if I export the database I see only:
KEY `index_products_on_shop_id` (`shop_id`)
What should I do in order to add
FOREIGN KEY (`shop_id`) REFERENCES Shop(`id`)
?
You can use the foreigner gem for adding foreign keys to your application. To get started add the following to your Gemfile
gem "foreigner"
After that you can easily add foreign keys in your migration like so:
add_foreign_key :products, :shops
This would add a foreign from product.shop_id to shop.id. See the documentation for more options like differently named keys or self-referencing tables.