From f29db836d561d3a770eb9b011f135ef86e2bf9ba Mon Sep 17 00:00:00 2001 From: paul Date: Fri, 20 Jul 2018 06:44:58 +0200 Subject: [PATCH 1/3] finding records will respect purposes --- activerecord/lib/active_record/core.rb | 1 + activerecord/lib/active_record/querying.rb | 8 +++++ activerecord/lib/active_record/relation.rb | 30 ++++++++++++++++--- .../active_record/relation/finder_methods.rb | 2 ++ .../active_record/relation/query_methods.rb | 17 ++++++++++- 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index e70ef9723d898..f1e5196083e5a 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -186,6 +186,7 @@ def find(*ids) # :nodoc: end def find_by(*args) # :nodoc: + # byebug return super if scope_attributes? || reflect_on_all_aggregations.any? hash = args.first diff --git a/activerecord/lib/active_record/querying.rb b/activerecord/lib/active_record/querying.rb index 60a55c3e25ba4..566785955549a 100644 --- a/activerecord/lib/active_record/querying.rb +++ b/activerecord/lib/active_record/querying.rb @@ -49,6 +49,14 @@ def find_by_sql(sql, binds = [], preparable: nil, &block) class_name: name } + # binds.each do + # column = "" + # column = binds.first.name unless not binds.first.name + # if self.attribute_names.include? column += "_aip" + # # in this case the query was based on a column that has an _aip column and therefore purposes attached + # end + # end + message_bus.instrument("instantiation.active_record", payload) do result_set.map { |record| instantiate(record, column_types, &block) } end diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 770d4cf48c663..b2f77890413ae 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -26,7 +26,7 @@ class Relation attr_reader :table, :klass, :loaded, :predicate_builder # ==================================== # !!! Altered by prails - attr_accessor :skip_preloading_value, :purpose_fields, :for_purpose + attr_accessor :skip_preloading_value, :purpose_fields, :for_purpose, :query_columns # ==================================== alias :model :klass alias :loaded? :loaded @@ -41,11 +41,12 @@ def initialize(klass, table: klass.arel_table, predicate_builder: klass.predicat @loaded = false @predicate_builder = predicate_builder @delegate_to_klass = false - @for_purpose = -1 # ====================================================== # !!! Added by prails # + @for_purpose = -1 + @query_columns = {} @purpose_fields = [] @klass.attribute_names.each do |attribute| if attribute[-4..-1] == "_aip" @@ -273,8 +274,12 @@ def records # :nodoc: end end + + # this sanitizes the attributs of the records themselves. This counts for normal relations and also for associations, if there are records left # checks each attribute's "_aip" field if the purpose is contained + records_to_delete = [] + if self.for_purpose and not self.purpose_fields.empty? @records.each do |record| record.attributes.each do |k,v| @@ -290,13 +295,30 @@ def records # :nodoc: if not purposes.include? self.for_purpose record[k] = nil end + + if not self.query_columns.blank? + if self.query_columns.include? k.to_sym + # in this case there was a query condition based on the columns present in @query_columns + # find_by e.g. also uses this as well as .where() queries. + # If records where found based on this but the column was not allowed for the given purpose, we have to delete the whole record + if not purposes.include? self.for_purpose + records_to_delete << record + end + end + end + end end end end - # byebug + @records_dup = @records.dup + records_to_delete.each do |record| + @records_dup.delete(record) + end - @records + # byebug + # @records + @records_dup end # Serializes the relation objects Array. diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 32784452f44a2..a1c4ead369789 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -79,6 +79,7 @@ def find(*args) # Post.find_by name: 'Spartacus', rating: 4 # Post.find_by "published_at < ?", 2.weeks.ago def find_by(arg, *args) + # byebug where(arg, *args).take rescue ::RangeError nil @@ -101,6 +102,7 @@ def find_by!(arg, *args) # Person.take(5) # returns 5 objects fetched by SELECT * FROM people LIMIT 5 # Person.where(["name LIKE '%?'", name]).take def take(limit = nil) + # byebug limit ? find_take_with_limit(limit) : find_take end diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 64e1c05cc22e7..3c77ceb442339 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -124,7 +124,11 @@ def for(*args) # byebug if args.size == 1 # und gott sprach: es darf nur einen purpose geben - self.for_purpose = args.first + if args.first.is_a? Integer + self.for_purpose = args.first + else + raise ArgumentError, "purpose-ID must be of type Integer." + end else # hier unterschiedliche exceptions raisen, je nachdem ob keiner oder zu viele purposes angegeben wurden if args.size < 1 @@ -606,6 +610,17 @@ def left_outer_joins!(*args) # :nodoc: # If the condition is any blank-ish object, then #where is a no-op and returns # the current relation. def where(opts = :chain, *rest) + # byebug + # =============================================================== + # Added by Prails + # + # =============================================================== + if not opts.blank? + self.query_columns = opts + end + + # =============================================================== + if :chain == opts WhereChain.new(spawn) elsif opts.blank? From a298ab7b23fd23cf00ffba9225a289cbf95b554c Mon Sep 17 00:00:00 2001 From: TPei Date: Fri, 20 Jul 2018 10:35:14 +0200 Subject: [PATCH 2/3] remove byebug --- activerecord/lib/active_record/core.rb | 4 ---- activerecord/lib/active_record/relation.rb | 6 ------ activerecord/lib/active_record/relation/finder_methods.rb | 1 - 3 files changed, 11 deletions(-) diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index e70ef9723d898..e1a0b2ecf8446 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -155,7 +155,6 @@ def inherited(child_class) # :nodoc: end def find(*ids) # :nodoc: - # byebug # We don't have cache keys for this stuff yet return super unless ids.length == 1 return super if block_given? || @@ -169,7 +168,6 @@ def find(*ids) # :nodoc: key = primary_key - # byebug statement = cached_find_by_statement(key) { |params| where(key => params.bind).limit(1) } @@ -283,9 +281,7 @@ def cached_find_by_statement(key, &block) end def relation - # byebug relation = Relation.create(self) - # byebug if finder_needs_type_condition? && !ignore_default_scope? relation.where!(type_condition) diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 86f8d9c8905ec..45c561f8aea98 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -33,7 +33,6 @@ class Relation alias :locked? :lock_value def initialize(klass, table: klass.arel_table, predicate_builder: klass.predicate_builder, values: {}) - # byebug @klass = klass @table = table @values = values @@ -52,7 +51,6 @@ def initialize(klass, table: klass.arel_table, predicate_builder: klass.predicat @purpose_fields << attribute[0..-5] end end - # byebug # ====================================================== end @@ -246,16 +244,12 @@ def explain # Converts relation objects to Array. def to_ary - # byebug records.dup - # byebug end alias to_a to_ary def records # :nodoc: - # byebug load - # byebug # ====================================================== # !!! Added by prails diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 32784452f44a2..f7613a187d25e 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -65,7 +65,6 @@ module FinderMethods # Person.where(name: 'Spartacus', rating: 4).pluck(:field1, :field2) # # returns an Array of the required fields. def find(*args) - # byebug return super if block_given? find_with_ids(*args) end From 64e583151a310339a86401a8fb15f23d34710112 Mon Sep 17 00:00:00 2001 From: TPei Date: Fri, 20 Jul 2018 10:36:00 +0200 Subject: [PATCH 3/3] remove byebug --- activerecord/lib/active_record/relation/finder_methods.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index a85dd375540b2..f7613a187d25e 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -78,7 +78,6 @@ def find(*args) # Post.find_by name: 'Spartacus', rating: 4 # Post.find_by "published_at < ?", 2.weeks.ago def find_by(arg, *args) - # byebug where(arg, *args).take rescue ::RangeError nil @@ -101,7 +100,6 @@ def find_by!(arg, *args) # Person.take(5) # returns 5 objects fetched by SELECT * FROM people LIMIT 5 # Person.where(["name LIKE '%?'", name]).take def take(limit = nil) - # byebug limit ? find_take_with_limit(limit) : find_take end