CanCanCan,如何在memcached

时间:2017-08-21 14:18:34

标签: ruby-on-rails ruby cancan cancancan dalli

将CanCan 1.4升级到CanCanCan 2.0之后,我再也无法将current_ability缓存到使用Dalli的memcached中。

我收到以下错误:

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'

我通过覆盖 app / controllers / application_controller.rb

中的current_ability来通过Dalli将CanCan.Ability::current_ability存储在memcached中
 def current_ability
     Rails.cache.fetch("#{current_user.profil.cache_key}::ability") do
       super
     end
 end

为什么我将current_ability存储在缓存中?

cancan可以减慢页面加载速度,因为我在很多控制器中都有很多自定义操作,每个页面都会重新加载所有功能......

有关缓存/优化/最佳实践的任何指示都将非常受欢迎。谢谢!

更新1

添加app / models / ability.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

打印一个能力对象(下面只是一个能力片段,但结构是相同的)这是我尝试存储在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]}

0 个答案:

没有答案