2

我正在使用Rails 5.0与Postgresql 9.5如何使用Rails在db中添加复合主键?

我需要添加复合主键到我的模型'User_achievement'(链接'用户'和'成就'模型,你可能会猜到)。

所以我尝试使用“composite_primary_keys”宝石。我遵循了所有的指示,但结果并不像我预期的那样。好像它不存在于“user_achievement”表根据信息由PSQL创建PKEY工具:

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) 

这里的模型和迁移代码:

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 

所以应该宝石改变数据库表?或者它只影响轨道的环境? 是否有改变db的唯一方法 - 在迁移中添加执行行?

回答

1

由于没有人发布任何有用的东西,我会分享我现在得到的东西。

Gem'composite_primary_key'(CPK)不会改变数据库中的任何内容,所以如果您仍然需要它 - 您应该手动执行它(在迁移中添加命令)。

CPK所做的唯一的事情就是用'理解'复合主键是什么来扩展rails,因为它最初没有并且显示错误。

无论如何,我发现在rails的应用程序中使用复合主键是非常复杂和有问题的,因为它使得使用其他宝石相当神经质(每一个新的宝石安装你记住某处可能出错)以及将来用cpks改变你的代码。对于不熟悉此功能的其他人,它也会使您的代码更难理解。所以你应该总是指定你已经使用过CPK。

一个非常好的选择是添加一个索引与'唯一'选项,技术上意味着完全相同,但不需要额外的头痛。

所以只有在你真的必须和没有其他解决方案的情况下才能使用它!