Pull to refresh

Comments 11

Я к злой магии ещё бы отнёс возможность устанавливать различные коллбеки прямо в модели. Иногда это сильно мешает пониманию того, почему что-то не работает или наоборот работает (ну например перед сохранением, какое-то поле зануляется). В случае же с коллбеками, которые вызываются перед удалением, всё ещё хуже. Есть два метода - destroy_all и delete_all. Первый подгружает все данные из бд, затем для каждой записи вызывает коллбеки, а потом уже удаляет запись, т. е. всего будет n запросов на удаление и один на подгрузку. А второй делает запрос вида DELETE FROM table where ..., т. е. является более эффективным, но не вызывает коллбеки. Всё вышеописанное может и приводит к не очевидному на первый взгляд поведению.

Да, отличный пример. Эти методы еще более коварны, когда необходимо каскадное удаление и остается от удаленного юзера какое-нибудь уведомление или связанная часть в случае с delete_all.

Такие проблемы можно решить на уровне БД, создав внешний ключ. Сейчас мы так и делаем - либо создаём внешний ключ с ON DELETE CASCADE, либо с ON DELETE SET NULL

Мы вообще пользуемся Sequel на не рельсовом руби-проекте, там эти вещи пишутся значительно очевиднее, в том числе ключи.

Мне ближе решение с использованием INNER_JOIN

Вы джойните Product к Clerk, при том, что, судя по параметрам метода (clerk_id), продавец у вас всего один. Вытащить его по ID отдельным запросом скорее всего будет дешевле, чем делать джоин. Более того, в "небольшой сети магазинов" кладовщиков обычно не очень много - десятки (ну сотни, если их там тысячи это уже не "небольшая сеть"), поэтому эти данные прекрасно кэшируются - меняются редко, места занимают не много, хит рэйт дают хороший. Т.е. этот дополнительный запрос даже и исполняться, чаще всего, не будет.

Все верно, для полутора землекопов (клерков) и циклом пройтись не дорого будет. Это я как раз пример "ничего страшного", а потом магазин превращается ВБ/Озон через год и все переписывать. Помечтать, если )

@Laranto жаль Вас расстраивать, но если через год маленький магазин превращается ВБ/Озон - вам и так и так всё переписывать.

Согласна, да еще и не на Руби возможно)

Интересная статья, смотивировала самому посмотреть как работают методы joins, left_joins и includes.
Получается самый интересный это includes + any? или includes + present?, такая связка не делает n+1.
Но самый хитрый тут это left_joins, может произойти так что загрузится только одно отношение и может показаться что present? помогает избегать `n+1`.

Спасибо! Тема только выглядит очевидной, но может ввести в заблуждение.
А еще есть eager_load: решает вроде похожую задачу, предотвращает n+1, использует LEFT JOIN в одном запросе. include делает 2 запроса, но если есть order или where, то тоже один с LEFT JOIN. При этом joins делает INNER JOIN.

Исходник rails с методами и описаниями: здесь.

И все это еще обмотать any?, present? или exists?. Голова кругом ))

Только to_sql приписывать и смотреть, а что в реальности. Может есть более элегантный способ?

Элегантный способ, это покрыть код тестом и посмотреть там, какой запрос создается.

Sign up to leave a comment.

Articles