CanCanCan, как хранить current_ability в memcached
После обновления CanCan 1.4 до CanCanCan 2.0 я больше не могу кешировать current_ability
в memcached с Dalli
,
Я получил ошибку ниже:
Cache write: profils/11-20170821121414000000::ability
Marshalling error for key 'development:profils/11-20170821121414000000::ability': can't dump hash with default proc
You are trying to cache a Ruby object which cannot be serialized to memcached.
/usr/local/rvm/gems/ruby-2.4.0@rails5.1.1/gems/dalli-2.7.6/lib/dalli/server.rb:414:in `dump'
Я храню current_ability
в memcached через Далли путем переопределения CanCan.Ability::current_ability
в app/controllers/application_controller.rb
def current_ability
Rails.cache.fetch("#{current_user.profil.cache_key}::ability") do
super
end
end
Почему я храню current_ability в кеше?
cancan замедление загрузки страницы, потому что у меня много настраиваемых действий во многих контроллерах, каждая страница перезагружает все возможности...
Любые указатели в отношении кеширования / оптимизации / лучших практик будут наиболее цениться. Спасибо!
обновление 1
Добавить приложение / модели / способность.rb
class Ability
include CanCan::Ability
def initialize(user)
alias_action :edit, :to => :read
role = user.profil
if role.label == 'administrateur'
can :manage, :all
else
role.rights.each do |right|
model = right.resource.constantize rescue nil
next unless model
[:read, :create, :update, :destroy].each do |capability|
can capability, model if right.send("#{capability}?")
end
end
# Custom actions
can([:collective, :collective_week, :presence, :day_details, :day_details_json], Movement) if can?(:read, Movement)
can(:quick_add, Movement) if can?(:create, Movement)
can([:actions, :set_action, :choose, :previous, :families_addresses, :ios,:families_members,:potential_relationships,:list_families,:list_decisions], Person) if can?(:read, Person)
can(:addresses, Family) if can?(:read, Family)
...
...
...
end
end
end
Обновление 2
Напечатайте объект Ability (ниже приведен лишь фрагмент способности, но структура та же самая). Это данные, которые я пытаюсь сохранить в memcached:
#<Ability:0x000000093030a0
@aliased_actions={:read=>[:index, :show, :edit], :create=>[:new], :update=>[:edit]},
@expanded_actions=
{[:index, :show, :edit]=>[:index, :show, :edit]},
@rules=
[#<CanCan::Rule:0x00000008fb3e18
@actions=[:read],
@base_behavior=true,
@block=nil,
@conditions={},
@match_all=false,
@subjects=[AcceptanceReason(id: integer, label: string, created_at: datetime, updated_at: datetime, institution_position: integer, acceptance_number: integer, department_type_id: integer)]>,
#<CanCan::Rule:0x00000008fb3760
@actions=[:create],
@base_behavior=true,
@block=nil,
@conditions={},
@match_all=false,
@subjects=[AcceptanceReason(id: integer, label: string, created_at: datetime, updated_at: datetime, institution_position: integer, acceptance_number: integer, department_type_id: integer)]>],
@rules_index=
{AcceptanceReason(id: integer, label: string, created_at: datetime, updated_at: datetime, institution_position: integer, acceptance_number: integer, department_type_id: integer)=>[0, 1, 2, 3],
Activity(id: integer, created_at: datetime, updated_at: datetime, institution_id: integer, label: string, activity_type_id: integer, employee_id: integer, department_id: integer, group_id: integer, beginning_at: date, ending_at: date, location: text, comments: text, objectif: text, evaluation: text, colour: string, collective_intervention_mean_id: integer, collective_intervention_status_id: integer, archive: boolean, activity_beginning_time: time, activity_ending_time: time, moyens_materiels: text, transports: text, autres_intervenants: text, budget: text, frequency: string)=>
[4, 5, 6, 7, 645],
ActivityCode(id: integer, label: string, created_at: datetime, updated_at: datetime)=>[8, 9, 10]}