Rails Composite Keys — настройка моделей и ассоциаций

#ruby-on-rails #activerecord #database-design #composite-primary-key

#ruby-on-rails #activerecord #база данных-дизайн #составной первичный ключ

Вопрос:

Я впервые использую Rails Composite Keys, и хотя я прочитал документы, я все еще не уверен, как правильно настроить модели.

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

Я получил это для своего составного ключа в качестве собственной модели. Это правильно?

 class ScheduledActivity < ActiveRecord::Base
  self.primary_keys = :provider_id, :activity_id
  belongs_to :activity
  belongs_to :provider
  has_many :schedules, :foreign_key => [:provider_id, :activity_id]
  has_many :prices, :foreign_key => [:provider_id, :activity_id]
end
  

Это для миграции БД:

 class CreateJoinTableScheduledActivities < ActiveRecord::Migration
  def change
    create_join_table :providers, :activities, table_name: :scheduled_activities do |t|
      t.index [:provider_id, :activity_id]
    end
  end
end
  

Как мне затем получать новые записи в таблице соединений при создании расписаний? Должен ли я использовать только belongs_to :scheduled_activity эту модель, т.Е. В таблице расписания нет идентификаторов провайдера и активности, и должен ли я написать отдельный хук для создания новых составных ключей?

(Кроме того, является ли это правильным вариантом использования для составных ключей в первую очередь ?!)

Заранее спасибо!

Ответ №1:

Ну, я не уверен, что это полностью отвечает на ваш вопрос, но если у вас есть составной уникальный ключ, вы можете сделать что-то вроде следующего.

В процессе миграции:

 add_index :scheduled_activities, [:provider_id, :activity_id], unique: true
  

В вашей модели соединения:

 belongs_to :activity
belongs_to :provider

validates :activity, presence: true, uniqueness: { scope: :provider }
  

Учитывая, что это больше, чем простая таблица соединений, возможно, вам следует рассмотреть возможность использования идентификаторов для идентификации каждого ScheduledActivity, тогда вы можете просто добавить эту ссылку в свою модель / таблицу расписания (таблица Schedule belongs_to :schedule_activity — schedules будет иметь ссылку на schedule_activity с атрибутом schedule_activity_id вместо использования составного ключа). Это сделало бы вещи намного проще и эффективнее.