module ReactiveRecord # The base collection class works with relationships # method overrides for scoped collections module ScopedCollection [:filter?, :collector?, :joins_with?, :related_records_for].each do |method| define_method(method) { |*args| @scope_description.send method, *args } end def set_pre_sync_related_records(related_records, _record = nil) @pre_sync_related_records = nil ReactiveRecord::Base.catch_db_requests do @pre_sync_related_records = filter_records(related_records) live_scopes.each do |scope| scope.set_pre_sync_related_records(@pre_sync_related_records) end end if filter? end def sync_scopes(related_records, record, filtering = true) filtering = @pre_sync_related_records && filtering && ReactiveRecord::Base.catch_db_requests do related_records = update_collection(related_records) end reload_from_db if !filtering && joins_with?(record) live_scopes.each { |scope| scope.sync_scopes(related_records, record, filtering) } ensure @pre_sync_related_records = nil end def update_collection(related_records) if collector? update_collector_scope(related_records) else related_records = filter_records(related_records) update_filter_scope(@pre_sync_related_records, related_records) end end def update_collector_scope(related_records) current = Set.new([*@collection]) (related_records - @pre_sync_related_records).each { |r| current << r } (@pre_sync_related_records - related_records).each { |r| current.delete(r) } replace(filter_records(current)) Set.new([*@collection]) end def update_filter_scope(before, after) if (collection || !@count.nil?) && before != after if collection (after - before).each { |r| push r } (before - after).each { |r| delete r } else @count += (after - before).count @count -= (before - after).count notify_of_change self # TODO: remove self .... and retest end end after end end end