Mongoid ruby, где запрос возвращает неправильные результаты

#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