Как получить данные redis, подключенные в приложении с несколькими рельсами? - PullRequest
1 голос
/ 15 января 2020

Я использую кеш redis для получения данных в моих приложениях rails. Проще говоря, я могу сказать, что у меня есть два приложения: первое основано на направляющих 4 , а второе - на направляющих 6 . Я должен использовать данные кэша в обоих приложениях.

В приложении rails 4 : - Я создал кэш в приложении rails 4 и успешно извлек данные.

Rails.cache.fetch("test_cache"){User.last}
=> #<User id: 100973, email: "xxxx.com", encrypted_password: "$2a$10$D8aOhoSWvNWeEQE2swAX2OEVIF5H0aY8sR/fGVQ3BhU...........> 

В приложении rails 6 : - Но когда я хочу загрузить тот же кеш в мое приложение rails 6, возникает ошибка.

Rails.cache.fetch("test_cache"){User.last}
Traceback (most recent call last):
        2: from (irb):18
        1: from (irb):18:in `rescue in irb_binding'
NameError (uninitialized constant ActiveRecord::AttributeSet)
Did you mean?  ActiveRecord::Attributes

Затем я пришел к одному решению, сохранить данные с помощью as_json

Rails.cache.fetch("test_cache"){User.last.as_json}

, которые успешно работают и извлекли данные в обоих приложениях, но у меня возникает еще одна проблема, как я могу получить доступ к model methods, associations etc etc... для одного и того же.

Любое предложение или идея?

1 Ответ

1 голос
/ 15 января 2020

Для нестроковых значений в кеше Rails использует Marshal.dump (а также сжимает его с помощью deflate для больших). Маршалловые данные можно рассматривать как нечто среднее между данными и кодом, поскольку они имеют ссылки на имена классов и внутреннюю структуру. Вот почему у него есть ограничения: он может быть распакован только с той же ruby версией (см. ruby документы по этому ), и приложение должно иметь одинаковые классы.

Очевидно, ActiveRecord::Base структура в рельсах 4 и рельсах 6, таким образом, несовместима при маршалинге.

Для обеспечения совместимости ваш единственный вариант - кэшировать только базовые c ruby типы и PORO, которые не ссылаются на какие-либо классы, которые отличаются в ваших приложениях. Ваша попытка с as_json делает именно это - хранит представление модели Ha sh.

Но на самом деле первый шаг - снова подумать о том, что именно и почему вы хотите кешировать, есть несколько мыслей для рассмотрения :

  1. Конечно, Redis / Memcache работает быстро, но доступ к нему все еще является запросом к базе данных с соответствующими издержками. Простые операции чтения из SQL DB (например, User.find(primary_key_value_here)) почти такие же быстрые.
  2. Модели AR имеют кэши для ассоциаций, также вы можете иметь некоторые запомненные данные, вы можете столкнуться с остановкой данных для этих
  3. Доступ к некэшированным ассоциациям по-прежнему приведет к вызовам базы данных
  4. Скорее всего, вы хотите кэшировать не саму модель, а способ ее более легко найти (например, если это результат некоторого дорогие вычисления) или некоторые производные данные. В первом случае достаточно сохранить идентификатор записи, во втором вы можете хранить что-то вроде хэша / PORO со всеми необходимыми данными, например:
hash = Rails.cache.fetch("last_registered_user"){
  User.last.yield_self{|u|
    {
      user_id: u.id,
      name: u.name,
      registered_at: u.created_at,
      invited_by: u.invited_by.name
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...