Поддельный составной первичный ключ? Рельсы - PullRequest
6 голосов
/ 08 марта 2011

У меня есть таблица с идентификатором | Patient_ID | Client_id | Active. Запись уникальна по методу Patient_id, client_id означает, что на каждого пациента должна приходиться только одна регистрация для каждого пациента. Обычно я бы сделал это первичным ключом, но в рельсах у меня есть идентификатор в качестве первичного ключа.

Каков наилучший способ обеспечить это? Validations

Ответы [ 3 ]

8 голосов
/ 08 марта 2011

Похоже, у вас есть модельное отношение:

class Client < ActiveRecord::Base
  has_many :patients, :through => :enrollments
  has_many :enrollments
end

class ClientPatient < ActiveRecord::Base
  belongs_to :client
  belongs_to :patient
end

class Patient < ActiveRecord::Base
  has_many :clients, :through => :enrollments
  has_many :enrollments
end

Чтобы применить ваше ограничение, я бы сделал это в ActiveRecord, чтобы вы получали надлежащую обратную связь при попытке сохранить запись, которая нарушает ограничение.Я бы просто изменил вашу модель ClientPatient следующим образом:

class Enrollment < ActiveRecord::Base
  belongs_to :client
  belongs_to :patient
  validates_uniqueness_of :patient_id, :scope => :client_id
end

Будьте осторожны, потому что, хотя это отлично подходит для небольших приложений, оно все же подвержено возможным условиям гонки, как описано здесь: http://apidock.com/rails/v3.0.5/ActiveRecord/Validations/ClassMethods/validates_uniqueness_of в разделе "Параллельность и целостность"

Как они там описывают, вы также должны добавить уникальный индекс в таблицу в базе данных.Это обеспечит два немедленных преимущества:

  • Проверка правильности и любые поиски в этой модели на основе этих двух идентификаторов будут выполняться быстрее (поскольку они проиндексированы)
  • Ограничение уникальности будетбыть принудительно установленным на стороне DB, и в редких случаях состояния гонки вы не получите неверные данные, сохраненные в базе данных ... хотя пользователи получат 500 Server Error, если вы не уловите ошибку.

В файле миграции добавьте следующее:

add_index :enrollments, [:patient_id, :client_id], :unique => true

Надеюсь, это было полезно:)

Редактирование (исправлены некоторые проблемы с именами и пара очевидных ошибок):

Тогда найти данные, которые вы ищете, очень просто:

Client.find_by_name("Bob Smith").patients
Patient.find_by_name("Henry Person").clients
1 голос
/ 08 марта 2011

Проверки работали бы ( Создайте резервные копии с уникальным индексом! ), но в vanilla Rails нет способа получить настоящий составной первичный ключ.Если вам нужен настоящий составной первичный ключ, вам понадобится гем / плагин - Composite_primary_keys - это тот, который я нашел, но я уверен, что есть и другие.

Надеюсь, этопомогает!

0 голосов
/ 08 марта 2011

Добавьте уникальное ограничение к вашей таблице через два столбца.Вот ссылка на MySQL http://dev.mysql.com/doc/refman/5.0/en/constraint-primary-key.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...