class RuboCop::Cop::Rails::OrderModelMacros
Constants
- CALLBACKS
- CLASS_METHODS
- DEFAULT_SCOPE
- DELEGATE
- ENUM
- GROUPED
- MSG
- MSG_MIXED_OUTER_GROUPS
- MSG_MIXED_WITHIN_GROUP
- MSG_OUTER_GROUPS
- MSG_WITHIN_GROUP
- SCOPE
Public Instance Methods
on_class(node)
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 25 def on_class(node) _name, superclass, body = *node return unless body && body.begin_type? return unless superclass && superclass.descendants.any? return unless %w(ActiveRecord ApplicationRecord).include?(superclass.descendants.first.const_name) targets = target_methods(body) return true if correct_grouping?(targets) && correct_within_groups?(targets) add_offense(body, message: @message || MSG) end
Private Instance Methods
all_targets()
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 100 def all_targets types = preferred_group_ordering .values .flatten .partition { |target_type| target_type.is_a?(Regexp) } { regexps: types.first, # array of Regexps names: types.last # array of Symbols } end
correct_grouping?(targets)
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 63 def correct_grouping?(targets) target_types = target_types(targets) type_order = preferred_group_ordering.keys squeezed = squeeze(target_types) a = type_order & squeezed b = squeezed & type_order single_groups?(squeezed) or set_outer_group_error_message(a, b, types: squeezed.select { |type| squeezed.count(type) > 1 }.uniq) && return a == b or set_outer_group_error_message(a, b) && false end
correct_within_groups?(targets)
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 44 def correct_within_groups?(targets) grouped = targets.group_by { |target| method_type(target) }.keep_if { |type, _targets| GROUPED.include?(type) } grouped.all? do |type, targets_for_type| ordered_for_type = preferred_group_ordering[type] squeezed = squeeze(targets_for_type.map(&:method_name)) mixed = squeezed != squeezed.uniq a = (ordered_for_type & squeezed) b = (squeezed & ordered_for_type) (!mixed && a == b) or set_within_group_error_message(type, a, b, mixed: mixed) && false end end
match(child)
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 90 def match(child) return false unless child && child.respond_to?(:send_type?) return child if matches_targets?(child.method_name) child.children && match(child.children.first) end
matches_targets?(declared)
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 96 def matches_targets?(declared) all_targets[:regexps].any? { |regex| regex === declared } || all_targets[:names].include?(declared) end
method_type(target)
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 128 def method_type(target) case target.method_name when DEFAULT_SCOPE then :default_scope when CLASS_METHODS then :class_method when ENUM then :enum when CALLBACKS then :callback when DELEGATE then :delegate when SCOPE then :scope when *association_macros then :association when *custom_macros then :custom when *gem_macros then :gem when *rails_macros then :rails when *validation_macros then :validation else raise "Unreachable code" end end
plural_form(group)
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 59 def plural_form(group) group.to_s + "s" end
set_outer_group_error_message(a, b, types: [])
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 145 def set_outer_group_error_message(a, b, types: []) return @message = MSG_MIXED_OUTER_GROUPS % { types: types.join(", ") } if types.any? first_error = a.zip(b).find { |x, y| x != y } @message = MSG_OUTER_GROUPS % {group1: plural_form(first_error.first), group2: plural_form(first_error.last)} end
set_within_group_error_message(type, a, b, mixed:)
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 151 def set_within_group_error_message(type, a, b, mixed:) return @message = MSG_MIXED_WITHIN_GROUP % { types: plural_form(type), type: type } if mixed first_error = a.zip(b).find { |x, y| x != y } @message = MSG_WITHIN_GROUP % {type: plural_form(type), method1: first_error.first, method2: first_error.last} end
single_groups?(targets)
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 76 def single_groups?(targets) squeeze(targets) == targets.uniq end
squeeze(targets)
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 80 def squeeze(targets) targets.each_with_object([]) do |el, squeezed| squeezed << el unless squeezed.last == el end end
target_mapping()
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 112 def target_mapping { default_scope: DEFAULT_SCOPE, class_method: CLASS_METHODS, enum: ENUM, association: association_macros, validation: validation_macros, callback: CALLBACKS, delegate: DELEGATE, rails: rails_macros, gem: gem_macros, custom: custom_macros, scope: SCOPE } end
target_methods(body)
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 86 def target_methods(body) body.children.compact.select(&method(:match)).map(&method(:match)) end
target_types(targets)
click to toggle source
# File lib/rubocop/cop/rails/order_model_macros.rb, line 40 def target_types(targets) targets.map { |target| method_type(target) } end