I'm using Rails 5.0 with Postgresql 9.5
I'm in need to add composite primary keys to my model 'User_achievement' (to link 'User' and 'Achievement' models as you may guess).
So I tried using the "composite_primary_keys" gem. I followed all the instructions, nevertheless, the result wasn't like I expected. Seems like it doesn't create pkey in the 'user_achievement' table according to the info by psql tool:
test1_development=> \d user_achievements
Table "public.user_achievements"
Column | Type | Modifiers
----------------+---------+-----------
user_id | integer |
achievement_id | integer |
uach_date | date |
Indexes:
"index_user_achievements_on_achievement_id" btree (achievement_id)
"index_user_achievements_on_user_id" btree (user_id)
Foreign-key constraints:
"fk_rails_4efde02858" FOREIGN KEY (user_id) REFERENCES users(id)
"fk_rails_c44f5b3b25" FOREIGN KEY (achievement_id) REFERENCES achievements(id)
Here's models and migrations' code:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
end
end
end
class CreateAchievements < ActiveRecord::Migration[5.0]
def change
create_table :achievements do |t|
t.string :ach_name
t.text :ach_desc
end
end
end
class CreateUserAchievements < ActiveRecord::Migration[5.0]
def change
create_table :user_achievements, id: false do |t|
t.belongs_to :user, :foreign_key => [:id]
t.belongs_to :achievement, :foreign_key => [:id]
t.date :uach_date
end
end
end
class Achievement < ApplicationRecord
has_many :user_achievements
end
class User < ApplicationRecord
has_many :user_achievements
end
class UserAchievement < ApplicationRecord
self.primary_keys = :user_id, :achievement_id
belongs_to :user, :foreign_key => [:id]
belongs_to :achievement, :foreign_key => [:id]
end
So should the gem alter db tables? or it influences just the rails' environment? Is there the only way to alter db - to add execute line in migration?
Since nobody have posted anything useful, I'll share what I've got by now.
Gem 'composite_primary_key' (CPK) doesn't change anything in database, so if you still want it - you should do it manually (add the command to migration).
The only thing CPK does is extending Rails with 'understanding' what a composite primary key is, since it originally doesn't have and shows an error.
Anyway I found it is very sohpisticated and problematic to use composite primary keys in Rails apps because it makes using other gems quite nerveous (with every new gem installation you keep in mind that somewhere something can go wrong) as well as changing your code with cpks in future. Also it makes your code harder to understand for other people who are not familliar with this feature. So you should always specify that you have used CPK.
A very good alternative is adding an index with 'unique' option which technically means quite the same but doesn't require additional headache.
So use it only if you really have to and there's no other less sophisticated solution!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With