Кэширование матрешки и ссылки на основе разрешений во фрагменте представления

У меня есть представление, в котором используется кэширование «Русская кукла», где кэшируется вся коллекция элементов, и каждый элемент в коллекции кэшируется индивидуально в этом кеше.

Однако каждый элемент в коллекции должен отображать ссылки для редактирования/удаления в зависимости от разрешений текущего пользователя, предоставленных через CanCan. Таким образом, пользователь А увидит ссылки редактирования/удаления только рядом со своими сообщениями, но не рядом с сообщениями пользователя Б.

Что ж, всякий раз, когда пользователь А создает сообщение, оно кэшируется с соответствующими ссылками на редактирование/удаление, поскольку они должны быть видны ему в зависимости от его разрешений. Но когда пользователь Б просматривает коллекцию, он показывает кешированный пост пользователя А вместе со ссылками на редактирование/удаление, которые он не должен видеть. Конечно, CanCan предотвращает выполнение этих действий редактирования/удаления, но ссылки все еще присутствуют.

Можно ли как-то создать отдельные кэши на основе current_user.id и предотвратить появление множества версий (почти) идентичного кэшированного контента?


person K.C. Barrett    schedule 30.10.2014    source источник


Ответы (1)


Можно ли как-то создать отдельные кэши на основе current_user.id и предотвратить появление множества версий (почти) идентичного кэшированного контента?

Вместо того, чтобы включать идентификатор пользователя в ключ кэша, вы можете включить разрешения пользователей. Это по-прежнему будет иметь дублированные копии контента, но масштабируется в соответствии с вашей моделью разрешений, а не количеством пользователей. Итак, вместо типичного:

<% cache("posts/all-#{Post.maximum(:updated_at).try(:to_i)}") do %>
...
<% end %>

вы можете создать кеш-ключ, например (при условии, что current_user возвращает аутентифицированного пользователя), и вам нужно только редактирование и чтение:

<% cache("posts/all-#{Post.maximum(:updated_at).try(:to_i)}-#{current_user.can?(:edit, Post) ? :edit : :read}") do %>
...
<% end %>

Обратите внимание, что генерация ключа кэша, вероятно, должна быть выделена в отдельный класс/вспомогательный метод.

person phillbaker    schedule 08.03.2015