Во время обзора первого модуля в Flatiron School наш инструктор подробно описал диаграмму взаимоотношений сущностей (ERD) между собаками и владельцами. Я уже видел диаграммы взаимосвязей, где линии соединяли все соответствующие части и описывали их взаимосвязь друг с другом, но инструктор добавил к диаграмме третий объект: Dog_Owner. В то время это казалось лишним шагом: почему бы просто не связать собаку и хозяина напрямую? Стиль ERD явно имеет возможность детализировать, может ли человек владеть множеством собак или у собаки может быть несколько владельцев, так почему бы не использовать это? На данный момент я решил, что было бы лучше поверить, что это хорошая практика, что она будет иметь больше смысла позже, и подумать о том, что промежуточная сущность имеет отношения между собаками и владельцами, которые будут представлены очень четко.

Мой инструктор подробно описал отношения has_many_through, а более прямой метод, который я представлял, - это отношения has_and_belongs_to_many. С тех пор я определенно заметил, что использование has_many_through может потребовать немного больше настроек, но обеспечивает гораздо большую гибкость и доступ к отношениям. В этом случае наш инструктор учил нас хорошей практике и заставлял нас избегать многих душевных страданий и замешательства, но все же важно увидеть альтернативу, если просто оценить лучший метод.

Примерно через две недели после этого, готовясь к оценке кода, я столкнулся с лабораторией кода, которая хотела, чтобы я установил связь между двумя классами Ruby. На наших уроках мы практиковались с использованием отношения has_many_through, поэтому я был сбит с толку, когда лаборатория указала нам пропустить создание этой третьей сущности. Чтобы установить пример:

Заказчик - | - ‹Официант› | -Шеф-повар

В этом случае у клиентов и шеф-поваров есть много друг друга через официантов (которых у них также много), и каждый официант будет принадлежать одному клиенту и одному шеф-повару. Это то, что Ruby будет называть has_many_through, типом отношений «многие ко многим». Лаборатория пыталась отказаться от официанта и напрямую связать клиента и шеф-повара. Для ERD это будет:

Заказчик ›- -‹ Шеф-повар

В этом случае клиенты и повара и принадлежат многим друг другу, и это второй тип отношения «многие ко многим» в Ruby, has_and_belongs_to_many. Это нетрудно концептуализировать или представить, но реализация этого в коде - вот где это становится необычным. Во время лабораторной работы я почти сразу создал бесконечный цикл из двух сущностей, пытающихся связать друг с другом. Будет создан новый Customer, он сохранит self в переменной класса, а затем создаст нового Chef, с которым он будет связан. Однако я создавал каждую сущность с помощью методов, а не. new и метод initialize, по крайней мере, не напрямую. Таким образом, будет создан новый Customer, который затем создаст нового Chef, который создаст себя, сохранит себя в переменной класса, а затем попытается установить связь с новым Customer. Затем это будет повторяться до бесконечности: новый клиент создает нового шеф-повара, который создает нового клиента, который создает нового шеф-повара ...

Я смог исправить это, заставив методы вызывать другие. new вместо вызова метода, в котором было. new, но как только он заработал, я мог только сравните это с альтернативой. В свою защиту has_and_belongs_to_many короче, чище и должен быть таким же функциональным. Что теряется при выборе использования has_and_belongs_to_many, так это доступ к этой третьей сущности между ними. Может быть, с клиентом и шеф-поваром или собакой и владельцем отношения не так уж и важны, и достаточно декларации has_many и own_to, но в других случаях отношения будут иметь собственные качества, за которыми стоит следить. Например, пассажир и пилот могут быть связаны через рейс. Полет будет осуществляться через авиакомпанию, иметь номер рейса, маршрут, продолжительность и, конечно же, полеты будут принадлежать Пассажиру и Пилоту. В этом случае сущность отношения очень важна или, по крайней мере, у нее есть много собственных качеств, которые стоит знать и которые не будут храниться где-либо еще.

После завершения модуля, думаю, я могу оглянуться назад и согласиться с тем, чтобы не преподавать has_and_belongs_to_many, особенно студентов, которые просто пытаются понять основы кодирования. Сначала это казалось велосипедом с тремя колесами, но оказалось, что третье колесо больше походило на раму велосипеда. В конце концов, использование has_many_through позволяет вам получить доступ и предоставить больше информации об отношениях, дает читателям вашего кода лучшее представление о том, как все устроено, и без значительного изменения производительности.