module Sequel::Plugins::UnusedAssociations::ClassMethods
Public Instance Methods
Source
# File lib/sequel/plugins/unused_associations.rb 284 def associate(type, assoc_name, opts=OPTS) 285 if !opts[:is_used] && @unused_associations_data && (data = @unused_associations_data[name]) && data[assoc_name.to_s] == 'unused' 286 return 287 end 288 289 super 290 end
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.
Source
# File lib/sequel/plugins/unused_associations.rb 275 def association_reflection(association) 276 uar = used_association_reflections 277 Sequel.synchronize{uar[association] ||= true} 278 super 279 end
Record access to association reflections to determine which associations are not used.
Source
# File lib/sequel/plugins/unused_associations.rb 461 def delete_unused_associations_files 462 _delete_unused_associations_file(@unused_associations_coverage_file) 463 _delete_unused_associations_file(@unused_associations_file) 464 end
Delete the unused associations coverage file and unused associations data file, if either exist.
Source
# File lib/sequel/plugins/unused_associations.rb 293 def freeze 294 used_association_reflections 295 super 296 end
Setup the used_association_reflections
storage before freezing
Source
# File lib/sequel/plugins/unused_associations.rb 445 def unused_association_options(opts=OPTS) 446 unused_associations_data = opts[:unused_associations_data] || Sequel.parse_json(File.binread(@unused_associations_file)) 447 448 unused_association_methods = [] 449 unused_associations_data.each do |sc, associations| 450 associations.each do |assoc, unused| 451 unless unused == 'unused' 452 unused_association_methods << [sc, assoc, set_unused_options_for_association({}, unused)] 453 end 454 end 455 end 456 unused_association_methods 457 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.
Source
# File lib/sequel/plugins/unused_associations.rb 418 def unused_associations(opts=OPTS) 419 unused_associations_data = opts[:unused_associations_data] || Sequel.parse_json(File.binread(@unused_associations_file)) 420 421 unused_associations = [] 422 unused_associations_data.each do |sc, associations| 423 associations.each do |assoc, unused| 424 if unused == 'unused' 425 unused_associations << [sc, assoc] 426 end 427 end 428 end 429 unused_associations 430 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.
Source
# File lib/sequel/plugins/unused_associations.rb 305 def update_associations_coverage(opts=OPTS) 306 coverage_result = opts[:coverage_result] || Coverage.result 307 module_mapping = {} 308 file = @unused_associations_coverage_file 309 310 coverage_data = if file && File.file?(file) 311 Sequel.parse_json(File.binread(file)) 312 else 313 {} 314 end 315 316 ([self] + descendants).each do |sc| 317 next if sc.associations.empty? || !sc.name 318 module_mapping[sc.send(:overridable_methods_module)] = sc 319 cov_data = coverage_data[sc.name] ||= {''=>[]} 320 cov_data[''].concat(sc.used_association_reflections.keys.map(&:to_s).sort).uniq! 321 end 322 323 coverage_result.each do |file, coverage| 324 coverage[:methods].each do |(mod, meth), times| 325 next unless sc = module_mapping[mod] 326 coverage_data[sc.name][meth.to_s] ||= 0 327 coverage_data[sc.name][meth.to_s] += times 328 end 329 end 330 331 if file 332 File.binwrite(file, Sequel.object_to_json(coverage_data)) 333 end 334 335 coverage_data 336 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
.
Source
# File lib/sequel/plugins/unused_associations.rb 346 def update_unused_associations_data(options=OPTS) 347 coverage_data = options[:coverage_data] || Sequel.parse_json(File.binread(@unused_associations_coverage_file)) 348 349 unused_associations_data = {} 350 351 ([self] + descendants).each do |sc| 352 next unless cov_data = coverage_data[sc.name] 353 reflection_data = cov_data[''] || [] 354 355 sc.association_reflections.each do |assoc, ref| 356 # Only report associations for the class they are defined in 357 next unless ref[:model] == sc 358 359 # Do not report associations using methods_module option, because this plugin only 360 # looks in the class's overridable_methods_module 361 next if ref[:methods_module] 362 363 info = {} 364 if reflection_data.include?(assoc.to_s) 365 info[:used] = [:reflection] 366 end 367 368 _update_association_coverage_info(info, cov_data, ref.dataset_method, :dataset_method) 369 _update_association_coverage_info(info, cov_data, ref.association_method, :association_method) 370 371 unless ref[:orig_opts][:read_only] 372 if ref.returns_array? 373 _update_association_coverage_info(info, cov_data, ref[:add_method], :adder) 374 _update_association_coverage_info(info, cov_data, ref[:remove_method], :remover) 375 _update_association_coverage_info(info, cov_data, ref[:remove_all_method], :clearer) 376 else 377 _update_association_coverage_info(info, cov_data, ref[:setter_method], :setter) 378 end 379 end 380 381 next if info.keys == [:missing] 382 383 if !info[:used] 384 (unused_associations_data[sc.name] ||= {})[assoc.to_s] = 'unused' 385 elsif unused = info[:unused] 386 if unused.include?(:setter) || [:adder, :remover, :clearer].all?{|k| unused.include?(k)} 387 [:setter, :adder, :remover, :clearer].each do |k| 388 unused.delete(k) 389 end 390 unused << :read_only 391 end 392 (unused_associations_data[sc.name] ||= {})[assoc.to_s] = unused.map(&:to_s) 393 end 394 end 395 end 396 397 if @unused_associations_file 398 File.binwrite(@unused_associations_file, Sequel.object_to_json(unused_associations_data)) 399 end 400 unless options[:keep_coverage] 401 _delete_unused_associations_file(@unused_associations_coverage_file) 402 end 403 404 unused_associations_data 405 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.
Source
# File lib/sequel/plugins/unused_associations.rb 270 def used_association_reflections 271 Sequel.synchronize{@used_association_reflections ||= {}} 272 end
Synchronize access to the used association reflections.
Private Instance Methods
Source
# File lib/sequel/plugins/unused_associations.rb 469 def _delete_unused_associations_file(file) 470 if file && File.file?(file) 471 File.unlink(file) 472 end 473 end
Delete the given file if it exists.
Source
# File lib/sequel/plugins/unused_associations.rb 477 def _update_association_coverage_info(info, coverage_data, meth, key) 478 type = case coverage_data[meth.to_s] 479 when 0 480 :unused 481 when Integer 482 :used 483 else 484 # Missing here means there is no coverage information for the 485 # the method, which indicates the expected method was never 486 # defined. In that case, it can be ignored. 487 :missing 488 end 489 490 (info[type] ||= []) << key 491 end
Update the info hash with information on whether the given method was called, according to the coverage information.
Source
# File lib/sequel/plugins/unused_associations.rb 510 def def_association(opts) 511 if !opts[:is_used] && @unused_associations_data && (data = @unused_associations_data[name]) && (unused = data[opts[:name].to_s]) 512 set_unused_options_for_association(opts, unused) 513 end 514 515 super 516 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.
Source
# File lib/sequel/plugins/unused_associations.rb 496 def set_unused_options_for_association(opts, unused) 497 opts[:read_only] = true if unused.include?('read_only') 498 opts[:no_dataset_method] = true if unused.include?('dataset_method') 499 opts[:no_association_method] = true if unused.include?('association_method') 500 opts[:adder] = nil if unused.include?('adder') 501 opts[:remover] = nil if unused.include?('remover') 502 opts[:clearer] = nil if unused.include?('clearer') 503 opts 504 end
Based on the value of the unused, update the opts hash with association options that will prevent unused association methods from being defined.