# frozen_string_literal: true module Phlexi module Form module FieldOptions module Multiple def multiple? options[:multiple] = options.fetch(:multiple) { calculate_multiple_field_value } end def multiple!(multiple = true) options[:multiple] = multiple self end private def calculate_multiple_field_value return true if reflection&.macro == :has_many return true if multiple_field_array_attribute? check_multiple_field_from_validators end def multiple_field_array_attribute? return false unless object.class.respond_to?(:columns_hash) column = object.class.columns_hash[key.to_s] return false unless column case object.class.connection.adapter_name.downcase when "postgresql" column.array? || (column.type == :string && column.sql_type.include?("[]")) end # || object.class.attribute_types[key.to_s].is_a?(ActiveRecord::Type::Serialized) rescue # Rails.logger.warn("Error checking multiple field array attribute: #{e.message}") false end def check_multiple_field_from_validators inclusion_validator = find_validator(:inclusion) length_validator = find_validator(:length) return false unless inclusion_validator || length_validator check_multiple_field_inclusion_validator(inclusion_validator) || check_multiple_field_length_validator(length_validator) end def check_multiple_field_inclusion_validator(validator) return false unless validator in_option = validator.options[:in] return false unless in_option.is_a?(Array) validator.options[:multiple] == true || (multiple_field_array_attribute? && in_option.size > 1) end def check_multiple_field_length_validator(validator) return false unless validator validator.options[:maximum].to_i > 1 if validator.options[:maximum] end end end end end