diff --git a/NEWS.md b/NEWS.md index d1c9c446..23136f4b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,8 @@ ## [unreleased] +- Fix a subtle bug on table access as in `table[:col]` in certain situations. + ## Release v2.3.1/v1.5.1 (20-12-2024) - Fallback to Ruby's Warning module if ActiveSupport doesn't exist. Relevant for old Rails versions. diff --git a/lib/arel_extensions/string_functions.rb b/lib/arel_extensions/string_functions.rb index 49cefa8e..c4f25851 100644 --- a/lib/arel_extensions/string_functions.rb +++ b/lib/arel_extensions/string_functions.rb @@ -47,14 +47,27 @@ def substring start, len = nil ArelExtensions::Nodes::Substring.new [self, start, len] end - def [](start, ind = nil) - start += 1 if start.is_a?(Integer) - if start.is_a?(Range) + # Return a [ArelExtensions::Nodes::Substring] if `start` is a [Range] or an + # [Integer]. + # + # Return the result to `self.send(start)` if it's a [String|Symbol]. The + # assumption is that you're trying to reach an [Arel::Table]'s + # [Arel::Attribute]. + # + # @note `ind` should be an [Integer|NilClass] if `start` is an [Integer]. + # It's ignored in all other cases. + def [](start, end_ = nil) + if start.is_a?(String) || start.is_a?(Symbol) + self.send(start) + elsif start.is_a?(Range) ArelExtensions::Nodes::Substring.new [self, start.begin + 1, start.end - start.begin + 1] - elsif start.is_a?(Integer) && !ind - ArelExtensions::Nodes::Substring.new [self, start, 1] + elsif start.is_a?(Integer) && !end_ + ArelExtensions::Nodes::Substring.new [self, start + 1, 1] + elsif start.is_a?(Integer) + start += 1 + ArelExtensions::Nodes::Substring.new [self, start, end_ - start + 1] else - ArelExtensions::Nodes::Substring.new [self, start, ind - start + 1] + raise ArgumentError, 'unrecognized argument types; can accept integers, ranges, or strings.' end end