class RuboCop::Cop::Rails::Date
This cop checks for the correct use of Date
methods, such as Date.today, Date.current etc.
Using Date.today is dangerous, because it doesn't know anything about Rails
time zone. You must use Time.zone.today instead.
The cop also reports warnings when you are using 'to_time' method, because it doesn't know about Rails
time zone either.
Two styles are supported for this cop. When EnforcedStyle is 'strict' then the Date
methods (today, current, yesterday, tomorrow) are prohibited and the usage of both 'to_time' and 'to_time_in_current_zone' is reported as warning.
When EnforcedStyle is 'flexible' then only 'Date.today' is prohibited and only 'to_time' is reported as warning.
@example
# no offense Time.zone.today Time.zone.today - 1.day # flexible Date.current Date.yesterday # always reports offense Date.today date.to_time # reports offense only when style is 'strict' date.to_time_in_current_zone
Constants
- BAD_DAYS
- MSG
- MSG_SEND
Public Instance Methods
# File lib/rubocop/cop/rails/date.rb, line 48 def on_const(node) mod, klass = *node.children # we should only check core Date class (`Date` or `::Date`) return unless (mod.nil? || mod.cbase_type?) && method_send?(node) check_date_node(node.parent) if klass == :Date end
# File lib/rubocop/cop/rails/date.rb, line 56 def on_send(node) return unless node.receiver && bad_methods.include?(node.method_name) return if safe_chain?(node) || safe_to_time?(node) add_offense(node, location: :selector, message: format(MSG_SEND, node.method_name)) end
Private Instance Methods
# File lib/rubocop/cop/rails/date.rb, line 114 def bad_days BAD_DAYS - good_days end
# File lib/rubocop/cop/rails/date.rb, line 118 def bad_methods style == :strict ? %i[to_time to_time_in_current_zone] : [:to_time] end
# File lib/rubocop/cop/rails/date.rb, line 67 def check_date_node(node) chain = extract_method_chain(node) return if (chain & bad_days).empty? method_name = (chain & bad_days).join('.') add_offense(node, location: :selector, message: format(MSG, "Date.#{method_name}", "Time.zone.#{method_name}")) end
# File lib/rubocop/cop/rails/date.rb, line 80 def extract_method_chain(node) [node, *node.each_ancestor(:send)].map(&:method_name) end
# File lib/rubocop/cop/rails/date.rb, line 110 def good_days style == :strict ? [] : %i[current yesterday tomorrow] end
# File lib/rubocop/cop/rails/date.rb, line 122 def good_methods style == :strict ? [] : TimeZone::ACCEPTED_METHODS end
checks that parent node of send_type and receiver is the given node
# File lib/rubocop/cop/rails/date.rb, line 86 def method_send?(node) return false unless node.parent && node.parent.send_type? node.parent.receiver == node end
# File lib/rubocop/cop/rails/date.rb, line 92 def safe_chain?(node) chain = extract_method_chain(node) (chain & bad_methods).empty? || !(chain & good_methods).empty? end
# File lib/rubocop/cop/rails/date.rb, line 98 def safe_to_time?(node) return unless node.method?(:to_time) if node.receiver.str_type? zone_regexp = /([+-][\d:]+|\dZ)\z/ node.receiver.str_content.match(zone_regexp) else node.arguments.one? end end