Last active
December 23, 2015 12:59
-
-
Save xeviknal/a0ba1f4ff022b99b69fe to your computer and use it in GitHub Desktop.
Monkey patching can method in order to reach evaluated permissions in a block
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Admin::CacheHelper | |
def cache_with_permissions(name=[], options = nil, &cache_block) | |
permission_version = options && options[:permission_version] || :v0 | |
permission_required = get_cache_key_for(name, permission_version, &cache_block) | |
name = name + permission_required | |
cache(name, options) { cache_block.call } | |
end | |
def get_cache_key_for(fragment_key, version, &cache_block) | |
permission_required = Camaloon::Cache::PermissionGatherer.gather([ :permission_version, version ] << fragment_key, cache_block) | |
permission_required.collect do |action, subject, extra_args| | |
[action, subject, current_ability.can?(action, subject, extra_args)].join "-" | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- cache_with_permissions([@order, I18n.locale]) do | |
h1 Ola | |
- if can?(:create, Design) | |
= render 'form' | |
user: | |
create_design? yes / no | |
... | |
def cache_with_permissions(keys, &block) | |
permisos_necesaris = Camaloon.cache.fetch("clau del tros") do | |
# Monkeypatch de can? i preparar el array per guardar els permissos | |
resultat = yield | |
@array_de_permisos_utilitzats | |
end | |
if resultat.nil? | |
cache(keys + permisos_necesaris(per curent user) do | |
yield | |
end | |
else | |
resultat | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PermissionGatherer | |
cattr_accessor :already_gathered | |
def self.gather(key, block) | |
if already_gathered | |
block.call | |
[] | |
else | |
Camaloon.cache(key) do | |
track_permissions(block) do | |
block.call | |
end | |
end | |
end | |
end | |
private | |
def self.track_permissions(cache_block, &block) | |
letting_recursivity do | |
klass = eval("self", cache_block.binding) | |
klass.class_eval do | |
attr_accessor :permissions | |
end | |
klass.instance_eval do | |
alias :can_without_register? :can? | |
self.permissions = [] | |
@swap_output_buffer = @output_buffer | |
@output_buffer = ActionView::OutputBuffer.new | |
def can?(action, subject, *extra_args) | |
if get_class? subject | |
subject = subject.class | |
elsif current_ability.has_block?(action, subject) | |
raise RuntimeException, "not supported" | |
end | |
self.permissions << [action, subject, extra_args] | |
can_without_register?(action, subject, extra_args) | |
end | |
def get_class?(subject) | |
!( subject.is_a?(String) || subject.is_a?(Symbol) || subject.respond_to?(:ancestors) ) && | |
subject.respond_to?(:class) | |
end | |
end | |
block.call | |
klass.instance_eval do | |
alias :can? :can_without_register? | |
undef :can_without_register? | |
@output_buffer = @swap_output_buffer | |
end | |
klass.instance_eval("self.permissions").uniq | |
end | |
end | |
def self.letting_recursivity(&block) | |
self.already_gathered = true | |
permissions = yield | |
self.already_gathered = false | |
permissions | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment