Module: Protector::Adapters::ActiveRecord::Relation
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/protector/adapters/active_record/relation.rb
Overview
Patches ActiveRecord::Relation
Instance Method Summary collapse
-
#calculate(*args) ⇒ Object
Merges current relation with restriction and calls real
calculate. - #count(*args) ⇒ Object
-
#exec_queries_with_protector(*args) ⇒ Object
Patches current relation to fulfill restriction and call real
exec_queries. -
#exists?(*args) ⇒ Boolean
Merges current relation with restriction and calls real
exists?. -
#protector_expand_inclusion(inclusion, results = [], base = [], klass = @klass) ⇒ Object
Indexes
includesformat by actual entity class. -
#protector_meta ⇒ Object
Gets DSL::Meta::Box of this relation.
-
#protector_substitute_includes(relation) ⇒ Object
Swaps
includeswithpreloadwhether it's not referenced or merges security scope of proper class otherwise. - #sum(*args) ⇒ Object
- #unscoped ⇒ Object
Instance Method Details
#calculate(*args) ⇒ Object
Merges current relation with restriction and calls real calculate
51 52 53 54 |
# File 'lib/protector/adapters/active_record/relation.rb', line 51 def calculate(*args) return super unless @protector_subject merge(.relation).unrestrict!.calculate *args end |
#count(*args) ⇒ Object
This is here cause NullRelation can return nil from count
41 42 43 |
# File 'lib/protector/adapters/active_record/relation.rb', line 41 def count(*args) super || 0 end |
#exec_queries_with_protector(*args) ⇒ Object
Patches current relation to fulfill restriction and call real exec_queries
Patching includes:
- turning
includes(that are not referenced for eager loading) intopreload - delaying built-in preloading to the stage where selection is restricted
- merging current relation with restriction (of self and every eager association)
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/protector/adapters/active_record/relation.rb', line 69 def exec_queries_with_protector(*args) return @records if loaded? return exec_queries_without_protector unless @protector_subject subject = @protector_subject relation = merge(.relation).unrestrict! relation = protector_substitute_includes(relation) # Preserve associations from internal loading. We are going to handle that # ourselves respecting security scopes FTW! associations, relation.preload_values = relation.preload_values, [] @records = relation.send(:exec_queries).each{|record| record.restrict!(subject)} # Now we have @records restricted properly so let's preload associations! associations.each do |association| ::ActiveRecord::Associations::Preloader.new(@records, association).run end @loaded = true @records end |
#exists?(*args) ⇒ Boolean
Merges current relation with restriction and calls real exists?
57 58 59 60 |
# File 'lib/protector/adapters/active_record/relation.rb', line 57 def exists?(*args) return super unless @protector_subject merge(.relation).unrestrict!.exists? *args end |
#protector_expand_inclusion(inclusion, results = [], base = [], klass = @klass) ⇒ Object
Indexes includes format by actual entity class
Turns {foo: :bar} into [[Foo, :foo], [Bar, {foo: :bar}]
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/protector/adapters/active_record/relation.rb', line 117 def (inclusion, results=[], base=[], klass=@klass) if inclusion.is_a?(Hash) (inclusion, results, base, klass) else Array(inclusion).each do |i| if i.is_a?(Hash) (i, results, base, klass) else results << [ klass.reflect_on_association(i.to_sym).klass, i.to_sym ] end end end results end |
#protector_meta ⇒ Object
Gets DSL::Meta::Box of this relation
29 30 31 32 33 |
# File 'lib/protector/adapters/active_record/relation.rb', line 29 def # We don't seem to require columns here as well # @klass.protector_meta.evaluate(@klass, @protector_subject, @klass.column_names) @klass..evaluate(@klass, @protector_subject) end |
#protector_substitute_includes(relation) ⇒ Object
Swaps includes with preload whether it's not referenced or merges
security scope of proper class otherwise
94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/protector/adapters/active_record/relation.rb', line 94 def protector_substitute_includes(relation) subject = @protector_subject if eager_loading? (includes_values + eager_load_values).each do |klass, path| relation = relation.merge(klass..evaluate(klass, subject).relation) end else relation.preload_values += includes_values relation.includes_values = [] end relation end |
#sum(*args) ⇒ Object
This is here cause NullRelation can return nil from sum
46 47 48 |
# File 'lib/protector/adapters/active_record/relation.rb', line 46 def sum(*args) super || 0 end |
#unscoped ⇒ Object
Unscoped relation drops properties and therefore should be re-restricted
36 37 38 |
# File 'lib/protector/adapters/active_record/relation.rb', line 36 def unscoped super.restrict!(@protector_subject) end |