У меня есть класс Family
, который включает в себя mother_id
и father_id
. С точки зрения модели семьи важно знать, какой родитель является матерью, а кто отец, но мать и отец Residents
имеют все те же атрибуты (то есть столбцы базы данных). Поэтому в идеале я бы хотел, чтобы мои файлы модели выглядели следующим образом:has_one с более чем одной возможной колонкой с внешним ключом
class Resident < ActiveRecord::Base
has_one :family, :dependent => :nullify, :foreign_key => :father_id
has_one :family, :dependent => :nullify, :foreign_key => :mother_id
attr_accessible :email, :cell, :first_name, :last_name
end
class Family < ActiveRecord::Base
belongs_to :father, :class_name => 'Resident', :foreign_key => 'father_id'
belongs_to :mother, :class_name => 'Resident', :foreign_key => 'mother_id'
attr_accessible :address, :city, :state, :number_of_children
end
Это не работает. my_family.mother
и my_family.father
работают, поэтому Rails, кажется, счастлив с двойным belongs_to
. Однако, my_dad.family == nil
, что указывает на то, что второе has_one
переопределяет первое. Это разумно, потому что в противном случае, что произойдет, если resident_id появился в обеих столбцах mother_id и father_id? (Хотя я планирую добавить проверку уровня модели, чтобы гарантировать, что это никогда не произойдет, has_one
не говорит о методах валидации.) Кроме того, что означает my_dad.family = Family.new
? Как бы ActiveRecord выбрать, следует ли вставить my_dad.id
в Family.mother_id
или Family.father_id
?
От this Stackoverflow question, я пришла в голову идея использовать разные имена, то есть изменить has_one
строки:
has_one :wife_and_kids, :class_name => 'Family', :dependent => :nullify, :foreign_key => :father_id
has_one :husband_and_kids, :class_name => 'Family', :dependent => :nullify, :foreign_key => :mother_id
Мои вопросы:
1) Есть ли лучший способ сделать это? Может быть, другая схема БД?
2) Является ли проверка уровня базы данных можно дополнить валидацию модели уровня, чтобы гарантировать, что my_dad.id
не может проявляться в обоих mother_id
и father_id
столбцов?
3) Можете ли вы назвать лучшие имена, чем husband_and_kids
/wife_and_kids
? (Правда, не программирования вопрос ...)
EDIT: Мне пришло в голову, чтобы добавить семейный добытчик:
def family
@family ||= self.wife_and_kids || self.husband_and_kids
end
after_save :reset_family
def reset_family
@family = nil
end
Это делает синтаксически чище (так как я на самом деле не был фанатом от [husband|wife]_and_kids
), не создавая никакой двусмысленности, так как нет сеттера.
Я не понимаю, почему он отвечает на мой второй вопрос. Если у резидента есть тип «мужчина», но я пытаюсь вставить его id в Family.mother_id, база данных не будет знать, что это неверно. –
Я полагаю, что это косвенно отвечает на второй вопрос, потому что он делает явные проверки ненужными. При создании новой записи, если вы ограничиваете себя созданием экземпляров только объектов Mother или объектов Father, нет никакой двусмысленности в отношении внешнего ключа. Объект Mother имеет внешний ключ: mother_id в семейной таблице, и это невозможно путать с: father_id – cdesrosiers
Но эта проверка выполняется в модели, то есть в приложении. Вопрос № 2 касается проверки уровня базы данных - т. Е. что, если в будущем другому нужно подключиться к базе данных - как я могу обеспечить, чтобы разработчики будущего приложения не смогли совершить ошибку, поставив отца в столбце mother_id? Когда вы rawn 'rails генерируете семейство моделей mother_id: integer: uniq', rails помещает в файл схемы: ' add_index "family", ["mother_id"],: name => "index_families_on_mother_id",: unique => true' Мне нужна аналогичная проверка, в которой говорится, что столбца mother_id не может быть введено в столбце father_id –