"В Вашем примере, видимо, UserRepository будет иметь методы addAddress($userId, $address), getAddress ($userId), saveUser($user, $address, $photos) или getUser($id, $fields) — чтобы получить пользователя с зависимыми сущностями" ок. Допустим. Я лишь хочу напомнить, что Пользователь - это актор. На него примерно 99.9% всего завязано, при таком подходе в UserRepository будет чуть менее чем всё, что касается пользователя(а его касается вообще всё) и поверьте, я видел такой трындец, получался классический God-class который назывался или UserController или UserRepository, не важно. И Вы правильно подметили, что ActiveRecord - это уже абстракция которая уже содержит необходимое разделение, если так уж хочется иметь слои, а не модели - всегда можно вынести запросы в билдер, при этом остается гибкость композиции и нет мешанины методов. Тогда логику работы с моделью/билдером можно вынести в сервис, связи таблиц, если не требуется запись, можно сделать в релейшенах модели и использовать with, а вот уже для записи создать отдельный сервис.