Как добавить составные первичные ключи в БД с помощью Rails?

Я использую Rails 5.0 с Postgresql 9.5

Мне нужно добавить составные первичные ключи к моей модели User_achievement (чтобы связать модели "Пользователь" и "Достижение", как вы можете догадаться).

Поэтому я попытался использовать драгоценный камень "component_primary_keys". Я следовал всем инструкциям, но результат оказался не таким, как я ожидал. Похоже, что он не создает pkey в таблице 'user_achievement' в соответствии с информацией инструмента psql:

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

Так должен ли гем изменить таблицы базы данных? или это влияет только на окружающую среду рельсов? Есть ли единственный способ изменить БД - добавить строку выполнения в миграцию?

1 ответ

Решение

Поскольку никто не опубликовал ничего полезного, я поделюсь тем, что у меня есть.

Gem 'component_primary_key' (CPK) ничего не меняет в базе данных, поэтому, если вы все еще хотите это сделать - вы должны сделать это вручную (добавьте команду в миграцию).

Единственное, что делает CPK, это расширяет Rails с "пониманием", что такое составной первичный ключ, поскольку он изначально не имеет и показывает ошибку.

В любом случае я обнаружил, что использовать сложные первичные ключи в приложениях Rails очень сложно и проблематично, потому что это делает использование других драгоценных камней весьма нервным (при каждой новой установке gem вы помните, что где-то что-то может пойти не так), а также изменяя код с помощью cpks в будущем. Также это усложняет понимание вашего кода для других людей, которые не знакомы с этой функцией. Поэтому вы всегда должны указывать, что вы использовали КПК.

Очень хорошая альтернатива - добавление индекса с уникальной опцией, которая технически означает то же самое, но не требует дополнительной головной боли.

Так что используйте его, только если вам действительно нужно, и нет другого, менее сложного решения!

Другие вопросы по тегам