Sha256: 1a09222955a2e0e9f8866c3f9f656c2c50b1cf46eba44216a2238ca1b0506c86

Contents?: true

Size: 1.88 KB

Versions: 2

Compression:

Stored size: 1.88 KB

Contents

# frozen_string_literal: true

module RuboCop
  module Cop
    # A mixin to extend cops for Active Record features
    module ActiveRecordHelper
      extend NodePattern::Macros

      def_node_search :find_set_table_name, <<~PATTERN
        (send self :table_name= {str sym})
      PATTERN

      def_node_search :find_belongs_to, <<~PATTERN
        (send nil? :belongs_to {str sym} ...)
      PATTERN

      def table_name(class_node)
        table_name = find_set_table_name(class_node).to_a.last&.first_argument
        return table_name.value.to_s if table_name

        namespaces = class_node.each_ancestor(:class, :module)
        [class_node, *namespaces]
          .reverse
          .map { |klass| klass.identifier.children[1] }.join('_')
          .tableize
      end

      # Resolve relation into column name.
      # It just returns column_name if the column exists.
      # Or it tries to resolve column_name as a relation.
      # It returns `nil` if it can't resolve.
      #
      # @param name [String]
      # @param class_node [RuboCop::AST::Node]
      # @param table [RuboCop::Rails::SchemaLoader::Table]
      # @return [String, nil]
      def resolve_relation_into_column(name:, class_node:, table:)
        return name if table.with_column?(name: name)

        find_belongs_to(class_node) do |belongs_to|
          next unless belongs_to.first_argument.value.to_s == name

          fk = foreign_key_of(belongs_to) || "#{name}_id"
          return fk if table.with_column?(name: fk)
        end
        nil
      end

      def foreign_key_of(belongs_to)
        options = belongs_to.last_argument
        return unless options.hash_type?

        options.each_pair.find do |pair|
          next unless pair.key.sym_type? && pair.key.value == :foreign_key
          next unless pair.value.sym_type? || pair.value.str_type?

          break pair.value.value.to_s
        end
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
rubocop-rails-2.5.1 lib/rubocop/cop/mixin/active_record_helper.rb
rubocop-rails-2.5.0 lib/rubocop/cop/mixin/active_record_helper.rb