出于移除目的,我想记录一个来自我的AR模型的方法。
我可以通过以下方式获得所有这些课程:
subclasses = [] ; ObjectSpace.each_object(Module) {|m| subclasses << m if m.ancestors.include? ActiveRecord::Base } ; subclasses.map(&:name)
但是我需要一个只列出在这些类上定义的方法的列表(实例和类方法),以及在其中注入logger语句的方法。
结果相当于将其插入到每个方法
中def foo
logger.info "#{class.name} - #{__method__}"
# ...
end
def self.foo
logger.info "#{name} - #{__method__}"
# ...
end
如果不将其实际添加到每个方法中,我该怎么做?
也许有些可怕的元?
答案 0 :(得分:1)
如果您只想要在课程中定义的方法,您可以这样做:
>> Project.instance_methods
=> ["const_get", "validates_associated", "before_destroy_callback_chain", "reset_mocha", "parent_name", "inspect", "slug_normalizer_block", "set_sequence_name", "require_library_or_gem", "method_exists?", "valid_keys_for_has_and_belongs_to_many_association=", "table_name=", "validate_find_options_without_friendly", "quoted_table_name" (another 100 or so methods)]
仅限您班级中定义的方法
>> Project.instance_methods(false)
=> ["featured_asset", "category_list", "before_save_associated_records_for_slugs", "asset_ids", "primary_asset", "friendly_id_options", "description", "description_plain"]
答案 1 :(得分:1)
您应该使用面向方面编程模式。在Ruby Aquarium gem中提供了AOP DSL。
在log_method_initializer.rb
目录中创建config/initializers/
。
require 'aquarium'
Aspect.new(:around, :calls_to => :all_methods,
:in_types => [ActiveRecord::Base] ) do |join_point, object, *args|
log "Entering: #{join_point.target_type.name}##{join_point.method_name}"
result = join_point.proceed
log "Leaving: #{join_point.target_type.name}##{join_point.method_name}"
result
end
将记录从ActiveRecord::Base
继承的类的每个方法调用。
答案 2 :(得分:0)
你有
AR :: Base.instance_methods
和 AR :: Base.class_eval“some string”
因此您可以使用它们在每个现有方法上添加标题。
答案 3 :(得分:0)
例如,方法调用可以使用此代理模式:
class BlankSlate
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
end
class MyProxy < BlankSlate
def initialize(obj, &proc)
@proc = proc
@obj = obj
end
def method_missing(sym, *args, &block)
@proc.call(@obj,sym, *args)
@obj.__send__(sym, *args, &block)
end
end
示例:
cust = Customer.first
cust = MyProxy.new(cust) do |obj, method_name, *args|
ActiveRecord::Base.logger.info "#{obj.class}##{method_name}"
end
cust.city
# This will log:
# Customer#city
灵感来自:http://onestepback.org/index.cgi/Tech/Ruby/BlankSlate.rdoc
您需要找到一种方法在ActiveRecord :: Base对象创建上应用此模式。
答案 4 :(得分:0)
对于水族馆来说,似乎添加method_options => :exclude_ancestor_methods
就可以了。
我的堆栈问题太深了。
来源 http://andrzejonsoftware.blogspot.com/2011/08/tracing-aspect-for-rails-application.html