Last active
August 7, 2023 02:06
-
-
Save willnet/31a255f66312a41b054ed9b5101cf4e9 to your computer and use it in GitHub Desktop.
get association models
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class InspectSaveChain | |
class << self | |
attr_accessor :indent | |
end | |
self.indent = 0 | |
def self.call | |
new.call | |
end | |
def initialize | |
ActiveRecord::Base.descendants.each do |klass| | |
next if klass.abstract_class | |
klass.before_save(prepend: true) do |model| | |
puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#before_save start" | |
InspectSaveChain.indent += 1 | |
end | |
klass.before_save do |model| | |
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 | |
end | |
klass.after_create do |model| | |
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 | |
end | |
klass.after_update do |model| | |
InspectSaveChain.indent -= 1 | |
puts "#{' ' * (InspectSaveChain.indent * 2)}#{model.class}#after_update end" | |
end | |
end | |
end | |
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_/) | |
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 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} start" | |
self.class.indent += 1 | |
elsif save_method?(tp) && !duplicate_save_method_call?(tp) | |
update_last_call(tp) | |
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 -= 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 | |
trace.enable | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment