module Sequel::Plugins::UnusedAssociations::ClassMethods
Public Instance Methods
If modifying associations, and this association is marked as not used, and the association does not include the specific :is_used option, skip defining the association.
# File lib/sequel/plugins/unused_associations.rb, line 283 def associate(type, assoc_name, opts=OPTS) if !opts[:is_used] && @unused_associations_data && (data = @unused_associations_data[name]) && data[assoc_name.to_s] == 'unused' return end super end
Record access to association reflections to determine which associations are not used.
# File lib/sequel/plugins/unused_associations.rb, line 274 def association_reflection(association) uar = used_association_reflections Sequel.synchronize{uar[association] ||= true} super end
Delete the unused associations coverage file and unused associations data file, if either exist.
# File lib/sequel/plugins/unused_associations.rb, line 460 def delete_unused_associations_files _delete_unused_associations_file(@unused_associations_coverage_file) _delete_unused_associations_file(@unused_associations_file) end
Setup the #used_association_reflections storage before freezing
# File lib/sequel/plugins/unused_associations.rb, line 292 def freeze used_association_reflections super end
Return an array of unused association options. These are associations some but not all of the association methods are used, according to the coverage information. Each entry in the array is an array of three elements. The first element is the class name string, the second element is the association name string, and the third element is a hash of association options that can be used in the association so it does not define methods that are not used.
Options:
- :unused_associations_data
-
The data to use for determining which associations are unused, which is returned from
update_unused_associations_data
. If not given, loads the data from the file specified by the :file plugin option.
# File lib/sequel/plugins/unused_associations.rb, line 444 def unused_association_options(opts=OPTS) unused_associations_data = opts[:unused_associations_data] || Sequel.parse_json(File.binread(@unused_associations_file)) unused_association_methods = [] unused_associations_data.each do |sc, associations| associations.each do |assoc, unused| unless unused == 'unused' unused_association_methods << [sc, assoc, set_unused_options_for_association({}, unused)] end end end unused_association_methods end
Return an array of unused associations. These are associations where none of the association methods are used, according to the coverage information. Each entry in the array is an array of two strings, with the first string being the class name and the second string being the association name.
Options:
- :unused_associations_data
-
The data to use for determining which associations are unused, which is returned from
update_unused_associations_data
. If not given, loads the data from the file specified by the :file plugin option.
# File lib/sequel/plugins/unused_associations.rb, line 417 def unused_associations(opts=OPTS) unused_associations_data = opts[:unused_associations_data] || Sequel.parse_json(File.binread(@unused_associations_file)) unused_associations = [] unused_associations_data.each do |sc, associations| associations.each do |assoc, unused| if unused == 'unused' unused_associations << [sc, assoc] end end end unused_associations end
Parse the coverage result, and return the coverage data for the associations for descendants of this class. If the plugin uses the :coverage_file option, the existing coverage file will be loaded if present, and before the method returns, the coverage file will be updated.
Options:
- :coverage_result
-
The coverage result to use. This defaults to
Coverage.result
.
# File lib/sequel/plugins/unused_associations.rb, line 304 def update_associations_coverage(opts=OPTS) coverage_result = opts[:coverage_result] || Coverage.result module_mapping = {} file = @unused_associations_coverage_file coverage_data = if file && File.file?(file) Sequel.parse_json(File.binread(file)) else {} end ([self] + descendants).each do |sc| next if sc.associations.empty? || !sc.name module_mapping[sc.send(:overridable_methods_module)] = sc cov_data = coverage_data[sc.name] ||= {''=>[]} cov_data[''].concat(sc.used_association_reflections.keys.map(&:to_s).sort).uniq! end coverage_result.each do |file, coverage| coverage[:methods].each do |(mod, meth), times| next unless sc = module_mapping[mod] coverage_data[sc.name][meth.to_s] ||= 0 coverage_data[sc.name][meth.to_s] += times end end if file File.binwrite(file, Sequel.object_to_json(coverage_data)) end coverage_data end
Parse the coverage data returned by update_associations_coverage, and return data on unused associations and unused association methods.
Options:
- :coverage_data
-
The coverage data to use. If not given, it is taken from the file specified by the :coverage_file plugin option.
- :keep_coverage
-
Do not delete the file specified by the :coverage_file plugin option, even if it exists.
# File lib/sequel/plugins/unused_associations.rb, line 345 def update_unused_associations_data(options=OPTS) coverage_data = options[:coverage_data] || Sequel.parse_json(File.binread(@unused_associations_coverage_file)) unused_associations_data = {} ([self] + descendants).each do |sc| next unless cov_data = coverage_data[sc.name] reflection_data = cov_data[''] || [] sc.association_reflections.each do |assoc, ref| # Only report associations for the class they are defined in next unless ref[:model] == sc # Do not report associations using methods_module option, because this plugin only # looks in the class's overridable_methods_module next if ref[:methods_module] info = {} if reflection_data.include?(assoc.to_s) info[:used] = [:reflection] end _update_association_coverage_info(info, cov_data, ref.dataset_method, :dataset_method) _update_association_coverage_info(info, cov_data, ref.association_method, :association_method) unless ref[:orig_opts][:read_only] if ref.returns_array? _update_association_coverage_info(info, cov_data, ref[:add_method], :adder) _update_association_coverage_info(info, cov_data, ref[:remove_method], :remover) _update_association_coverage_info(info, cov_data, ref[:remove_all_method], :clearer) else _update_association_coverage_info(info, cov_data, ref[:setter_method], :setter) end end next if info.keys == [:missing] if !info[:used] (unused_associations_data[sc.name] ||= {})[assoc.to_s] = 'unused' elsif unused = info[:unused] if unused.include?(:setter) || [:adder, :remover, :clearer].all?{|k| unused.include?(k)} [:setter, :adder, :remover, :clearer].each do |k| unused.delete(k) end unused << :read_only end (unused_associations_data[sc.name] ||= {})[assoc.to_s] = unused.map(&:to_s) end end end if @unused_associations_file File.binwrite(@unused_associations_file, Sequel.object_to_json(unused_associations_data)) end unless options[:keep_coverage] _delete_unused_associations_file(@unused_associations_coverage_file) end unused_associations_data end
Synchronize access to the used association reflections.
# File lib/sequel/plugins/unused_associations.rb, line 269 def used_association_reflections Sequel.synchronize{@used_association_reflections ||= {}} end
Private Instance Methods
Delete the given file if it exists.
# File lib/sequel/plugins/unused_associations.rb, line 468 def _delete_unused_associations_file(file) if file && File.file?(file) File.unlink(file) end end
Update the info hash with information on whether the given method was called, according to the coverage information.
# File lib/sequel/plugins/unused_associations.rb, line 476 def _update_association_coverage_info(info, coverage_data, meth, key) type = case coverage_data[meth.to_s] when 0 :unused when Integer :used else # Missing here means there is no coverage information for the # the method, which indicates the expected method was never # defined. In that case, it can be ignored. :missing end (info[type] ||= []) << key end
If modifying associations, and this association has unused association methods, automatically set the appropriate options so the unused association methods are not defined, unless the association explicitly uses the :is_used options.
# File lib/sequel/plugins/unused_associations.rb, line 509 def def_association(opts) if !opts[:is_used] && @unused_associations_data && (data = @unused_associations_data[name]) && (unused = data[opts[:name].to_s]) set_unused_options_for_association(opts, unused) end super end
Based on the value of the unused, update the opts hash with association options that will prevent unused association methods from being defined.
# File lib/sequel/plugins/unused_associations.rb, line 495 def set_unused_options_for_association(opts, unused) opts[:read_only] = true if unused.include?('read_only') opts[:no_dataset_method] = true if unused.include?('dataset_method') opts[:no_association_method] = true if unused.include?('association_method') opts[:adder] = nil if unused.include?('adder') opts[:remover] = nil if unused.include?('remover') opts[:clearer] = nil if unused.include?('clearer') opts end