activerecord-hackery / ransack

Object-based searching.
https://activerecord-hackery.github.io/ransack/
MIT License
5.66k stars 799 forks source link

NoMethodError: undefined method `value' for #<Arel::SelectManager #1467

Open spaghetticode opened 9 months ago

spaghetticode commented 9 months ago

I'm experiencing this issue starting from Ransack 3.2 which removes the support for Rails 6 and some ancillary code.

The issue is happening here and is caused by the fact that in my context the right predicate for a Arel::Nodes::In predicate is a Arel::SelectManager rather than a Arel::Nodes::Casted, so we can't call #value on it:

module Ransack
  module Nodes
    class Condition < Node
      # ...
      def casted_array?(predicate)
        predicate.value.is_a?(Array) && predicate.is_a?(Arel::Nodes::Casted)
      end

The fix should be pretty simple: just check for the class before calling #value on the predicate.

For more context, the previous implementation didn't raise because there was an extra support method that hid the fact that the predicate may not respond to either #val or #value:

        def casted_array?(predicate)
          value_from(predicate).is_a?(Array) && predicate.is_a?(Arel::Nodes::Casted)
        end

        def value_from(predicate)
          if predicate.respond_to?(:value)
            predicate.value # Rails 6.1
          elsif predicate.respond_to?(:val)
            predicate.val # Rails 6.0
          end
        end

So, in my case this was equivalent to nil.is_a?(Array) && predicate.is_a?(Arel::Nodes::Casted)