#ruby #mongoid
#ruby #mongoid
Вопрос:
У меня есть класс User, который встраивает сообщения_many. Сообщение имеет поле «источник». Я пытаюсь получить сообщение с определенным «источником»:
m = user.messages.where(source: 'reward').first
Я получаю ноль, так как их нет. Затем я добавляю его сам и снова запускаю запрос, но он по-прежнему возвращает nil. Когда я делаю вместо: m = user.messages.to_a.find {|m| m.source == 'reward'}
Это работает, как и ожидалось. Похоже, что здесь есть некоторое кэширование, которое после первого запроса сохраняет данные и игнорирует следующую вставку, но я не могу найти способ отключить его (QueryCache отключен и не имеет значения).
Что это может быть?
Комментарии:
1. можете ли вы попробовать запустить user.reload, а затем снова запустить запрос? Если это работает, то это, вероятно, проблема с кешем. Если это не так, я бы предположил ошибку в реализации where встроенного объекта.
2. Если я сохраняю и перезагружаю, это работает, но тогда я предпочитаю решение to_a. Вопрос в том, зачем нужна перезагрузка? какой кэш здесь используется и как я могу это предотвратить?
3. Таким образом, это подтверждает ваши подозрения, что это проблема с кэшем. Я бы открыл ошибку для проекта monoid по адресу jira.mongodb.org/projects/MONGOID/issues
Ответ №1:
Запросы к встроенным ассоциациям выполняются в процессе приложения. Если user
загружается, и вы добавляете больше сообщений этому пользователю, используя что-либо другое, кроме загруженного user
объекта (например, оболочку mongo или другой экземпляр Rails console), сообщения в загруженном user
не будут обновляться. См https://docs.mongodb.com/mongoid/master/tutorials/mongoid-relations/#querying-loaded-associations .
-
Если вам нужны только данные из встроенных ассоциаций, запросите модель верхнего уровня с соответствующей проекцией, чтобы получить встроенную ассоциацию. См. https://docs.mongodb.com/mongoid/master/tutorials/mongoid-queries/#projection .
-
Если вам нужны данные как из модели верхнего уровня, так и из встроенной ассоциации, перезагрузите модель верхнего уровня, как предложено в комментарии.
Комментарии:
1. Я добавляю сообщения загруженному пользователю, используя загруженного пользователя в той же консоли
Ответ №2:
Возможным обходным путем может быть запрос встроенной ассоциации. В вашем случае ваш запрос будет выглядеть следующим образом:
m = user.where('message.source' => 'reward').first
Больше примеров здесь: https://docs.mongodb.com/mongoid/master/tutorials/mongoid-relations/index.html#querying-embedded-associations