Моделирование has_one "активного" ребенка среди has_many детей - PullRequest
0 голосов
/ 22 мая 2018

У меня есть модель:

class Group < ActiveRecord::Base
  has_many :progressions
  has_one :active_progression, class_name: "Progression"
end

И дочерний элемент:

class Progression < ActiveRecord::Base
  belongs_to :group
end

Я знаю, что соглашение гласит, что я должен создать отдельный внешний ключ внутри Progression, чтобы связать активныйпрогрессия с идентификатором группы (так работает has_one).

Однако, ИМХО, логичнее сохранять «активный» дочерний идентификатор в модели группы.

Изменить: Причина заключается в том, что сохранение идентификатора группы в модели прогрессии как active_group_id или что-то подобное семантически сбивает с толку и открывает возможность иметь несколько активных прогрессий, связанных с группой, что, очевидно, неверно.

Редактировать 2: Кроме того, Прогрессия должна быть активной для нескольких групп.Создание дополнительной таблицы соединений кажется излишним, если только я смог сохранить «активный» идентификатор ребенка в модели группы.

Я прочитал несколько постов, где люди путают основное значение has_one, предполагая, чтоделает то же самое, что и belongs_to, но для родителя.Я знаю, что это не так.has_one делает противоположное belongs_to, т. Е. Ищет ключ в аналоге вместо вызывающей модели.

Если Rails не предоставляет метод для создания ассоциации такого рода, что является наиболееRailsy решение?

1 Ответ

0 голосов
/ 22 мая 2018

Одной из опций может быть метод на Group, например:

def active_progression
  progressions.all.find { |p| p.id == active_progress_id }
end

Преимущество использования метода состоит в том, что, если вы в любом случае обычно зацикливаетесь на всех последовательностях, вы делаете только один вызов SQL.Метод ищет активную прогрессию из существующего набора записей.

Обратите внимание, что используется метод Ruby #find (https://ruby -doc.org / core-2.2.3 / Enumerable.html # method-i-find ), а не метод ActiveRecord #find.

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