class RuboCop::Cop::Rails::RelativeDateConstant

This cop checks whether constant value isn't relative date. Because the relative date will be evaluated only once.

@example

# bad
class SomeClass
  EXPIRED_AT = 1.week.since
end

# good
class SomeClass
  EXPIRES = 1.week

  def self.expired_at
    EXPIRES.since
  end
end

# good
class SomeClass
  def self.expired_at
    1.week.since
  end
end

Constants

MSG
RELATIVE_DATE_METHODS

Public Instance Methods

on_casgn(node) click to toggle source
# File lib/rubocop/cop/rails/relative_date_constant.rb, line 38
def on_casgn(node)
  nested_relative_date(node) do |method_name|
    add_offense(node, message: message(method_name)) do |corrector|
      autocorrect(corrector, node)
    end
  end
end
on_masgn(node) click to toggle source
# File lib/rubocop/cop/rails/relative_date_constant.rb, line 46
def on_masgn(node)
  lhs, rhs = *node

  return unless rhs&.array_type?

  lhs.children.zip(rhs.children).each do |(name, value)|
    next unless name.casgn_type?

    nested_relative_date(value) do |method_name|
      add_offense(offense_range(name, value), message: message(method_name)) do |corrector|
        autocorrect(corrector, node)
      end
    end
  end
end
on_or_asgn(node) click to toggle source
# File lib/rubocop/cop/rails/relative_date_constant.rb, line 62
def on_or_asgn(node)
  relative_date_or_assignment(node) do |method_name|
    add_offense(node, message: format(MSG, method_name: method_name))
  end
end

Private Instance Methods

autocorrect(corrector, node) click to toggle source
# File lib/rubocop/cop/rails/relative_date_constant.rb, line 70
def autocorrect(corrector, node)
  return unless node.casgn_type?

  scope, const_name, value = *node
  return unless scope.nil?

  indent = ' ' * node.loc.column
  new_code = ["def self.#{const_name.downcase}",
              "#{indent}#{value.source}",
              'end'].join("\n#{indent}")

  corrector.replace(node.source_range, new_code)
end
message(method_name) click to toggle source
# File lib/rubocop/cop/rails/relative_date_constant.rb, line 84
def message(method_name)
  format(MSG, method_name: method_name)
end
nested_relative_date(node, &callback) click to toggle source
# File lib/rubocop/cop/rails/relative_date_constant.rb, line 92
def nested_relative_date(node, &callback)
  return if node.block_type?

  node.each_child_node do |child|
    nested_relative_date(child, &callback)
  end

  relative_date(node, &callback)
end
offense_range(name, value) click to toggle source
# File lib/rubocop/cop/rails/relative_date_constant.rb, line 88
def offense_range(name, value)
  range_between(name.loc.expression.begin_pos, value.loc.expression.end_pos)
end