Skip to content

Instantly share code, notes, and snippets.

@willnet
Last active August 7, 2023 02:06
Show Gist options
  • Select an option

  • Save willnet/31a255f66312a41b054ed9b5101cf4e9 to your computer and use it in GitHub Desktop.

Select an option

Save willnet/31a255f66312a41b054ed9b5101cf4e9 to your computer and use it in GitHub Desktop.

Revisions

  1. willnet revised this gist Aug 7, 2023. 1 changed file with 14 additions and 19 deletions.
    33 changes: 14 additions & 19 deletions inspect_save_chain.rb
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,9 @@
    class InspectSaveChain
    class << self
    attr_accessor :indent, :indent_stack
    attr_accessor :indent
    end

    self.indent = 0
    self.indent_stack = []

    def self.call
    new.call
    @@ -16,28 +15,25 @@ def initialize
    klass.before_save(prepend: true) do |model|
    puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save start"
    InspectSaveChain.indent += 1
    InspectSaveChain.indent_stack.push(1)
    end
    klass.before_save do |model|
    InspectSaveChain.indent -= InspectSaveChain.indent_stack.pop unless InspectSaveChain.indent_stack.empty?
    InspectSaveChain.indent -= 1
    puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save end"
    end
    klass.set_callback(:create, :after) do |model|
    puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create start"
    InspectSaveChain.indent += 1
    InspectSaveChain.indent_stack.push(1)
    end
    klass.after_create do |model|
    InspectSaveChain.indent -= InspectSaveChain.indent_stack.pop unless InspectSaveChain.indent_stack.empty?
    InspectSaveChain.indent -= 1
    puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create end"
    end
    klass.set_callback(:update, :after) do |model|
    puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update start"
    InspectSaveChain.indent += 1
    InspectSaveChain.indent_stack.push(1)
    end
    klass.after_update do |model|
    InspectSaveChain.indent -= InspectSaveChain.indent_stack.pop unless InspectSaveChain.indent_stack.empty?
    InspectSaveChain.indent -= 1
    puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update end"
    end
    end
    @@ -75,29 +71,28 @@ def update_last_return(tp)
    self.last_return_method = tp.method_id
    end



    def call
    trace = TracePoint.new(:call, :return) do |tp|
    if tp.event == :call
    if autosave_method?(tp)
    update_last_call(tp)
    puts "#{' ' * (self.class.indent * 2)}#{tp.self.class.name}##{tp.method_id}"
    puts "#{' ' * (self.class.indent * 2)}#{tp.self.class.name}##{tp.method_id} start"
    self.class.indent += 1
    elsif save_method?(tp) && !duplicate_save_method_call?(tp)
    if autosave_to_save?(tp)
    self.class.indent += 1
    self.class.indent_stack.push(2)
    else
    self.class.indent_stack.push(1)
    end
    update_last_call(tp)
    puts "#{' ' * (self.class.indent * 2)}#{tp.self.class.name}##{tp.method_id}"
    puts "#{' ' * (self.class.indent * 2)}#{tp.self.class.name}##{tp.method_id} start"
    self.class.indent += 1
    end
    else # :return
    if save_method?(tp) && !duplicate_save_method_return?(tp)
    self.class.indent -= self.class.indent_stack.pop unless self.class.indent_stack.empty?
    self.class.indent -= 1
    update_last_return(tp)
    puts "#{' ' * (self.class.indent * 2)}#{tp.self.class.name}##{tp.method_id} end"
    end

    if autosave_method?(tp)
    self.class.indent -= 1
    puts "#{' ' * (self.class.indent * 2)}#{tp.self.class.name}##{tp.method_id} end"
    end
    end
    end
  2. willnet revised this gist Aug 4, 2023. 1 changed file with 33 additions and 13 deletions.
    46 changes: 33 additions & 13 deletions inspect_save_chain.rb
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,10 @@
    class InspectSaveChain
    class << self
    attr_accessor :indent
    attr_accessor :indent, :indent_stack
    end

    self.indent = 0
    self.indent_stack = []

    def self.call
    new.call
    @@ -12,12 +13,33 @@ def self.call
    def initialize
    ActiveRecord::Base.descendants.each do |klass|
    next if klass.abstract_class
    klass.before_save(prepend: true) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save start" }
    klass.before_save { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save end" }
    klass.set_callback(:create, :after) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create start" }
    klass.after_create { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create end" }
    klass.set_callback(:update, :after) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update start" }
    klass.after_update { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update end" }
    klass.before_save(prepend: true) do |model|
    puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save start"
    InspectSaveChain.indent += 1
    InspectSaveChain.indent_stack.push(1)
    end
    klass.before_save do |model|
    InspectSaveChain.indent -= InspectSaveChain.indent_stack.pop unless InspectSaveChain.indent_stack.empty?
    puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save end"
    end
    klass.set_callback(:create, :after) do |model|
    puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create start"
    InspectSaveChain.indent += 1
    InspectSaveChain.indent_stack.push(1)
    end
    klass.after_create do |model|
    InspectSaveChain.indent -= InspectSaveChain.indent_stack.pop unless InspectSaveChain.indent_stack.empty?
    puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create end"
    end
    klass.set_callback(:update, :after) do |model|
    puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update start"
    InspectSaveChain.indent += 1
    InspectSaveChain.indent_stack.push(1)
    end
    klass.after_update do |model|
    InspectSaveChain.indent -= InspectSaveChain.indent_stack.pop unless InspectSaveChain.indent_stack.empty?
    puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update end"
    end
    end
    end

    @@ -53,9 +75,7 @@ def update_last_return(tp)
    self.last_return_method = tp.method_id
    end

    def indent_stack
    @indent_stack ||= []
    end


    def call
    trace = TracePoint.new(:call, :return) do |tp|
    @@ -66,17 +86,17 @@ def call
    elsif save_method?(tp) && !duplicate_save_method_call?(tp)
    if autosave_to_save?(tp)
    self.class.indent += 1
    indent_stack.push(2)
    self.class.indent_stack.push(2)
    else
    indent_stack.push(1)
    self.class.indent_stack.push(1)
    end
    update_last_call(tp)
    puts "#{' ' * (self.class.indent * 2)}#{tp.self.class.name}##{tp.method_id}"
    self.class.indent += 1
    end
    else # :return
    if save_method?(tp) && !duplicate_save_method_return?(tp)
    self.class.indent -= indent_stack.pop unless indent_stack.empty?
    self.class.indent -= self.class.indent_stack.pop unless self.class.indent_stack.empty?
    update_last_return(tp)
    end
    end
  3. willnet revised this gist Aug 4, 2023. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions inspect_save_chain.rb
    Original file line number Diff line number Diff line change
    @@ -14,9 +14,9 @@ def initialize
    next if klass.abstract_class
    klass.before_save(prepend: true) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save start" }
    klass.before_save { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save end" }
    set_callback(:create, :after) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create start" }
    klass.set_callback(:create, :after) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create start" }
    klass.after_create { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create end" }
    set_callback(:update, :after) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update start" }
    klass.set_callback(:update, :after) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update start" }
    klass.after_update { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update end" }
    end
    end
  4. willnet revised this gist Aug 4, 2023. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions inspect_save_chain.rb
    Original file line number Diff line number Diff line change
    @@ -14,9 +14,9 @@ def initialize
    next if klass.abstract_class
    klass.before_save(prepend: true) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save start" }
    klass.before_save { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save end" }
    klass.after_create(prepend: true) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create start" }
    set_callback(:create, :after) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create start" }
    klass.after_create { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create end" }
    klass.after_update(prepend: true) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update start" }
    set_callback(:update, :after) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update start" }
    klass.after_update { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update end" }
    end
    end
  5. willnet revised this gist Aug 3, 2023. 1 changed file with 5 additions and 3 deletions.
    8 changes: 5 additions & 3 deletions inspect_save_chain.rb
    Original file line number Diff line number Diff line change
    @@ -14,8 +14,10 @@ def initialize
    next if klass.abstract_class
    klass.before_save(prepend: true) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save start" }
    klass.before_save { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save end" }
    klass.after_save(prepend: true) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_save start" }
    klass.after_save { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_save end" }
    klass.after_create(prepend: true) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create start" }
    klass.after_create { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_create end" }
    klass.after_update(prepend: true) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update start" }
    klass.after_update { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update end" }
    end
    end

    @@ -81,4 +83,4 @@ def call
    end
    trace.enable
    end
    end
    end
  6. willnet revised this gist Jun 8, 2023. 1 changed file with 20 additions and 8 deletions.
    28 changes: 20 additions & 8 deletions inspect_save_chain.rb
    Original file line number Diff line number Diff line change
    @@ -1,13 +1,25 @@
    class InspectSaveChain
    class << self
    attr_accessor :indent
    end

    self.indent = 0

    def self.call
    new.call
    end

    def initialize
    @indent = 0
    ActiveRecord::Base.descendants.each do |klass|
    next if klass.abstract_class
    klass.before_save(prepend: true) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save start" }
    klass.before_save { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save end" }
    klass.after_save(prepend: true) { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_save start" }
    klass.after_save { |model| puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_save end" }
    end
    end

    attr_accessor :indent, :last_call_method, :last_call_class, :last_return_method, :last_return_class
    attr_accessor :last_call_method, :last_call_class, :last_return_method, :last_return_class

    def autosave_method?(tp)
    tp.method_id.match?(/autosave_associated_records_for_/)
    @@ -48,25 +60,25 @@ def call
    if tp.event == :call
    if autosave_method?(tp)
    update_last_call(tp)
    puts "#{' ' * (indent * 2)}#{tp.self.class.name}##{tp.method_id}"
    puts "#{' ' * (self.class.indent * 2)}#{tp.self.class.name}##{tp.method_id}"
    elsif save_method?(tp) && !duplicate_save_method_call?(tp)
    if autosave_to_save?(tp)
    self.indent += 1
    self.class.indent += 1
    indent_stack.push(2)
    else
    indent_stack.push(1)
    end
    update_last_call(tp)
    puts "#{' ' * (indent * 2)}#{tp.self.class.name}##{tp.method_id}"
    self.indent += 1
    puts "#{' ' * (self.class.indent * 2)}#{tp.self.class.name}##{tp.method_id}"
    self.class.indent += 1
    end
    else # :return
    if save_method?(tp) && !duplicate_save_method_return?(tp)
    self.indent -= indent_stack.pop unless indent_stack.empty?
    self.class.indent -= indent_stack.pop unless indent_stack.empty?
    update_last_return(tp)
    end
    end
    end
    trace.enable
    end
    end
    end
  7. willnet revised this gist Jun 8, 2023. 2 changed files with 72 additions and 26 deletions.
    72 changes: 72 additions & 0 deletions inspect_save_chain.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,72 @@
    class InspectSaveChain
    def self.call
    new.call
    end

    def initialize
    @indent = 0
    end

    attr_accessor :indent, :last_call_method, :last_call_class, :last_return_method, :last_return_class

    def autosave_method?(tp)
    tp.method_id.match?(/autosave_associated_records_for_/)
    end

    def save_method?(tp)
    tp.method_id == :save || tp.method_id == :save!
    end

    def duplicate_save_method_call?(tp)
    last_call_method == tp.method_id && last_call_class == tp.self.class
    end

    def duplicate_save_method_return?(tp)
    last_return_method == tp.method_id && last_return_class == tp.self.class
    end

    def autosave_to_save?(tp)
    (tp.method_id == :save || tp.method_id == :save!) && last_call_method&.match?(/autosave_associated_records_for_/)
    end

    def update_last_call(tp)
    self.last_call_class = tp.self.class
    self.last_call_method = tp.method_id
    end

    def update_last_return(tp)
    self.last_return_class = tp.self.class
    self.last_return_method = tp.method_id
    end

    def indent_stack
    @indent_stack ||= []
    end

    def call
    trace = TracePoint.new(:call, :return) do |tp|
    if tp.event == :call
    if autosave_method?(tp)
    update_last_call(tp)
    puts "#{' ' * (indent * 2)}#{tp.self.class.name}##{tp.method_id}"
    elsif save_method?(tp) && !duplicate_save_method_call?(tp)
    if autosave_to_save?(tp)
    self.indent += 1
    indent_stack.push(2)
    else
    indent_stack.push(1)
    end
    update_last_call(tp)
    puts "#{' ' * (indent * 2)}#{tp.self.class.name}##{tp.method_id}"
    self.indent += 1
    end
    else # :return
    if save_method?(tp) && !duplicate_save_method_return?(tp)
    self.indent -= indent_stack.pop unless indent_stack.empty?
    update_last_return(tp)
    end
    end
    end
    trace.enable
    end
    end
    26 changes: 0 additions & 26 deletions inspect_save_chaing.rb
    Original file line number Diff line number Diff line change
    @@ -1,26 +0,0 @@
    class InspectSaveChain
    def self.call
    indent = 0
    last_call_method = nil
    last_call_class = nil
    last_return_method = nil
    last_return_class = nil
    trace = TracePoint.new(:call, :return) do |tp|
    if tp.event == :call
    if (tp.method_id.match?(/autosave_associated_records_for_/) || tp.method_id == :save || tp.method_id == :save!) && !(last_call_method == tp.method_id && last_call_class == tp.self.class)
    last_call_class = tp.self.class
    last_call_method = tp.method_id
    puts "#{' ' * (indent * 2)}#{tp.self.class.name}##{tp.method_id}"
    indent += 1 if (tp.method_id == :save || tp.method_id == :save!)
    end
    else # :return
    if (tp.method_id == :save || tp.method_id == :save!) && !(last_return_method == tp.method_id && last_return_class == tp.self.class)
    indent -= 1
    last_return_class = tp.self.class
    last_return_method = tp.method_id
    end
    end
    end
    trace.enable
    end
    end
  8. willnet revised this gist Jun 1, 2023. 1 changed file with 26 additions and 0 deletions.
    26 changes: 26 additions & 0 deletions inspect_save_chaing.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    class InspectSaveChain
    def self.call
    indent = 0
    last_call_method = nil
    last_call_class = nil
    last_return_method = nil
    last_return_class = nil
    trace = TracePoint.new(:call, :return) do |tp|
    if tp.event == :call
    if (tp.method_id.match?(/autosave_associated_records_for_/) || tp.method_id == :save || tp.method_id == :save!) && !(last_call_method == tp.method_id && last_call_class == tp.self.class)
    last_call_class = tp.self.class
    last_call_method = tp.method_id
    puts "#{' ' * (indent * 2)}#{tp.self.class.name}##{tp.method_id}"
    indent += 1 if (tp.method_id == :save || tp.method_id == :save!)
    end
    else # :return
    if (tp.method_id == :save || tp.method_id == :save!) && !(last_return_method == tp.method_id && last_return_class == tp.self.class)
    indent -= 1
    last_return_class = tp.self.class
    last_return_method = tp.method_id
    end
    end
    end
    trace.enable
    end
    end
  9. willnet created this gist Apr 13, 2023.
    34 changes: 34 additions & 0 deletions inspect_associations.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,34 @@
    require 'set'

    class InspectAssociations
    def self.call(model)
    new.call(model)
    end

    def call(model)
    return if set.include?(model)
    set.add(model)

    model.class.reflections.keys.each do |name|
    reflection = model.class.reflections[name]

    assoc = model.association(name.to_sym)
    if reflection.collection?
    children = assoc.reader
    children.each { |child| call(child) }
    else
    child = assoc.reader
    call(child) if child
    end
    end
    pp set
    end

    private

    attr_reader :model

    def set
    @set ||= Set.new
    end
    end