module Scrivito # # This class represents an attribute definition. # # @api public # class AttributeDefinition # # @!attribute [r] name # @api public # @return [String] the name of the attribute. # # @!attribute [r] type # @api public # @return [String] the type of the attribute. # attr_reader :name, :type def initialize(name, type, options = {}) @name, @type, @options = name.to_s, type.to_s, options.with_indifferent_access assert_valid_options end # # Allowed values for an attribute. # # @api public # @return [Array] allowed values if +type+ is +enum+ or +multienum+ or an empty array # otherwise. If no values have been specified, an empty array is returned. # def values if type == 'enum' || type == 'multienum' @options[:values] || [] else [] end end # # Valid classes of a +reference+ or a +referencelist+ attribute. # # @api beta # # @raise [Scrivito::ScrivitoError] if +type+ is neither +reference+, nor +referencelist+. # @return [Array] valid classes specified using the # {Scrivito::AttributeContent::ClassMethods#attribute only} option. # @return +nil+ if no valid classes has been specified. # def valid_classes assert_restrictable @valid_classes end AttributeContent::ATTRIBUTE_TYPES.each do |attribute_type| define_method "#{attribute_type}?" do type == attribute_type end end def as_json hash = { name: name, type: type, } if enum? || multienum? hash[:validValues] = values end if (reference? || referencelist?) && valid_classes hash[:validClasses] = valid_classes.map(&:name) end hash end private def assert_valid_options @options.assert_valid_keys(:values, 'values', :only, 'only') if values = @options[:values] values.each(&method(:assert_valid_value)) end if only = @options[:only] assert_restrictable @valid_classes = [only].flatten @valid_classes.each(&method(:assert_valid_restriction_class)) end end def assert_valid_value(value) unless value.is_a?(String) raise ScrivitoError, %{#{value.class} is not allowed as value for #{type} attribute "#{name}".} end if value == '' raise ScrivitoError, %{Empty string is not allowed as value for #{type} attribute "#{name}".} end end def assert_restrictable unless %w[reference referencelist].include?(type) raise ScrivitoError, "#{type} attribute \"#{name}\" has no restrictions: "\ 'only reference and referencelist attributes can be restricted with the "only" option.' end end def assert_valid_restriction_class(obj_class) unless obj_class.is_a?(Class) && BasicObj > obj_class raise ScrivitoError, "Cannot restrict attribute \"#{name}\" to #{obj_class.inspect}: "\ "#{obj_class} is not a valid model class." end end end end