class Ransack::Predicate

def detect_and_strip_from_string!(str)

def detect_and_strip_from_string!(str)
  if p = detect_from_string(str)
    str.sub! /_#{p}$/, ''.freeze
    p
  end
end

def detect_from_string(str)

def detect_from_string(str)
  names_by_decreasing_length.detect { |p| str.end_with?("_#{p}") }
end

def eql?(other)

def eql?(other)
  self.class == other.class &&
  self.name == other.name
end

def format(val)

def format(val)
  if formatter
    formatter.call(val)
  else
    val
  end
end

def hash

def hash
  name.hash
end

def initialize(opts = {})

def initialize(opts = {})
  @name = opts[:name]
  @arel_predicate = opts[:arel_predicate]
  @type = opts[:type]
  @formatter = opts[:formatter]
  @validator = opts[:validator] ||
    lambda { |v| v.respond_to?(:empty?) ? !v.empty? : !v.nil? }
  @compound = opts[:compound]
  @wants_array = opts.fetch(:wants_array,
    @compound || Constants::IN_NOT_IN.include?(@arel_predicate))
end

def named(name)

def named(name)
  Ransack.predicates[name.to_s]
end

def names

def names
  Ransack.predicates.keys
end

def names_by_decreasing_length

def names_by_decreasing_length
  names.sort { |a, b| b.length <=> a.length }
end

def negative?

def negative?
  @name.include?("not_".freeze)
end

def validate(vals, type = @type)

def validate(vals, type = @type)
  vals.any? { |v| validator.call(type ? v.cast(type) : v.value) }
end