class MongoidAbility::Ability
Attributes
owner[RW]
Public Class Methods
new(owner)
click to toggle source
# File lib/mongoid_ability/ability.rb, line 31 def initialize(owner) @owner = owner inherited_locks = owner.respond_to?(owner.class.inherit_from_relation_name) ? owner.inherit_from_relation.flat_map(&:locks_relation) : [] inherited_locks = LocksDecorator.new(inherited_locks) owner_locks = owner.respond_to?(owner.class.locks_relation_name) ? owner.locks_relation : [] self.class.subject_root_classes.each do |cls| cls_list = [cls] + cls.descendants cls_list.each do |subcls| # if 2 of the same, prefer open locks = subcls.default_locks.for_subject_type(subcls).group_by(&:group_key_for_calc).flat_map do |_, locks| locks.detect(&:open?) || locks.first end # if 2 of the same, prefer open locks += inherited_locks.for_subject_type(subcls).group_by(&:group_key_for_calc).flat_map do |_, locks| locks.detect(&:open?) || locks.first end # if 2 of the same, prefer open locks += owner_locks.for_subject_type(subcls).group_by(&:group_key_for_calc).flat_map do |_, locks| locks.detect(&:open?) || locks.first end selected_locks = locks.group_by(&:group_key_for_calc).flat_map do |_, locks| # prefer last one, i.e. the one closest to owner locks.last end selected_locks.sort(&Lock.sort).each do |lock| apply_lock_rule(lock) end end end end
subject_classes()
click to toggle source
# File lib/mongoid_ability/ability.rb, line 19 def self.subject_classes Object.descendants.select do |cls| cls.included_modules.include?(MongoidAbility::Subject) end end
subject_root_classes()
click to toggle source
# File lib/mongoid_ability/ability.rb, line 25 def self.subject_root_classes subject_classes.reject do |cls| cls.superclass.included_modules.include?(MongoidAbility::Subject) end end
Public Instance Methods
marshal_dump()
click to toggle source
# File lib/mongoid_ability/ability.rb, line 9 def marshal_dump @rules end
marshal_load(array)
click to toggle source
# File lib/mongoid_ability/ability.rb, line 13 def marshal_load(array) Array(array).each do |rule| add_rule(rule) end end
model_adapter(model_class, action, options = {})
click to toggle source
# File lib/mongoid_ability/ability.rb, line 69 def model_adapter(model_class, action, options = {}) @model_adapter ||= {} @model_adapter[model_class] ||= {} @model_adapter[model_class][action] ||= {} @model_adapter[model_class][action][options] ||= begin adapter_class = CanCan::ModelAdapters::AbstractAdapter.adapter_class(model_class) # include all rules that apply for descendants as well # so the adapter can exclude include subclasses from critieria rules = ([model_class] + model_class.descendants).inject([]) do |res, cls| res += relevant_rules_for_query(action, cls) res.uniq end adapter_class.new(model_class, rules, options) end end
Private Instance Methods
apply_lock_rule(lock)
click to toggle source
# File lib/mongoid_ability/ability.rb, line 87 def apply_lock_rule(lock) ability_type = lock.outcome ? :can : :cannot cls = lock.subject_class options = lock.options options = options.merge(id: convert_to_bson(lock.subject_id)) if lock.id_lock? action = lock.action send ability_type, action, cls, options end
convert_to_bson(id)
click to toggle source
# File lib/mongoid_ability/ability.rb, line 96 def convert_to_bson(id) return id unless id.is_a?(String) return id unless BSON::ObjectId.legal?(id) BSON::ObjectId.from_string(id) end