Created
October 30, 2016 23:03
-
-
Save iagopiimenta/8c936fa8cd968fa0c11b258695f80e88 to your computer and use it in GitHub Desktop.
Mongoid 3.1.6 - Rails 3.2 - accessed_fields
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
# lib/accessed_fields.rb | |
module AccessedFields | |
def self.included(klass) | |
klass.extend(ClassMethods) | |
return unless klass.respond_to?(:fields) | |
klass.fields.keys.each do |field_name| | |
klass.wrap_default_method(field_name) | |
end | |
klass.class_eval do | |
alias_method :id, :_id | |
alias_method :id=, :_id= | |
end | |
end | |
def accessed_fields | |
accessed_fields_history.map do |field_info| | |
field_info[0] | |
end.uniq | |
end | |
def accessed_fields_history | |
@accessed_fields_history ||= [] | |
end | |
module ClassMethods | |
def field(*args) | |
super(*args) | |
wrap_default_method(args[0]) | |
end | |
def wrap_default_method(method) | |
mod = Module.new | |
mod.class_eval do | |
define_method(method) do | |
__register_call(method.to_s) | |
super() | |
end | |
define_method("#{method}=") do |value| | |
__register_call(method.to_s) | |
super(value) | |
end | |
private | |
def __register_call(field) | |
backtrace = Rails.backtrace_cleaner.clean(caller) | |
accessed_fields_history << [ | |
field, | |
backtrace[1..-1], | |
Time.current.to_f | |
] | |
end | |
end | |
prepend mod | |
end | |
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
# lib/afm.rb | |
# Based on https://gist.github.com/kddeisz/64a976d73ad44edf1d9fbf529b9f780e | |
require 'logger' | |
module Afm | |
class Railtie < Rails::Railtie | |
initializer 'afm.action_controller' do | |
ActiveSupport.on_load(:action_controller) do | |
include ControllerExtensions | |
end | |
end | |
end | |
module ControllerExtensions | |
Result = Struct.new(:class_name, :accessed, :unused, :history) do | |
def to_log | |
@to_log ||= "#{class_name}:\n Unused: #{unused.sort.join(', ')}\n Used: #{accessed.sort.join(', ')}\n #{backtrace}\n" | |
end | |
def backtrace | |
history.map do |field_info| | |
"\n " + field_info[0..1].join("\n ") | |
end.join("\n ") | |
end | |
end | |
def self.included(base) | |
base.after_filter :report_accessed_fields | |
end | |
private | |
def report_accessed_fields | |
found = [] | |
Afm.registry.each do |record| | |
accessed = record.accessed_fields | |
history = record.accessed_fields_history | |
unused = (record.attributes.keys - accessed) | |
next if unused.empty? | |
found << Result.new(record.class.name, accessed, unused, history) | |
end | |
if found.any? | |
Afm.logger.info("#{controller_name}##{action_name}") | |
found.sort_by(&:to_log).each { |result| Afm.logger.info(" #{result.to_log}") } | |
Afm.logger.info("\n") | |
end | |
ensure | |
Afm.clear_registry | |
end | |
end | |
module ModelExtensions | |
def self.included(base) | |
base.after_initialize :register_in_afm | |
end | |
private | |
def register_in_afm | |
Afm.register(self) | |
end | |
end | |
class << self | |
def clear_registry | |
@registry = nil | |
end | |
def logger | |
@logger ||= Logger.new(Rails.root.join('log', 'afm.log')) | |
end | |
def register(record) | |
registry << record | |
end | |
def registry | |
@registry ||= [] | |
end | |
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
# on application.rb : | |
# # require File.expand_path('../../lib/afm', __FILE__) | |
# config/initializers/mongoid_initializer.rb | |
require_dependency 'accessed_fields' | |
module Mongoid | |
alias __original_register_model register_model | |
def register_model(klass) | |
__original_register_model(klass) | |
klass.include AccessedFields | |
klass.include Afm::ModelExtensions | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment