Есть ли документация для типов столбцов Rails?

Я ищу больше, чем простой список типов на этой странице:

:primary_key,: string,: text,: integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary,: boolean

но есть ли какая-либо документация, которая на самом деле определяет эти поля?

в частности:

  • в чем разница между :string и :text?
  • между :float и :decimal?
  • каковы отличительные особенности :time, :timestamp и :datetime?

документированы ли нюансы этих типов где-либо?

EDIT:точки реализаций DB-платформы не имеют отношения к вопросу, который я пытаюсь задать. если, скажем, :datetime не имеет определенного предназначенного значения в документации Rails, тогда что делают db-adapter-writers при выборе соответствующий тип столбца?

2 ответов


рекомендации, построенные на личном опыте:

  • строка:
    • ограничено 255 символами (в зависимости от СУБД)
    • используйте для коротких текстовых полей (имена, электронные письма и т. д.)
  • текст:
    • неограниченная длина (в зависимости от СУБД)
    • используйте для комментариев, сообщений в блогах и т. д. Общее эмпирическое правило: если он захвачен через textarea, используйте текст. Для ввода текстовые поля, используйте string.
  • целое:

    из Rails master branch souce код я нашел:

    аннотация mysql_adapter

    #activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
    
      NATIVE_DATABASE_TYPES = {
        primary_key: "bigint auto_increment PRIMARY KEY",
        string:      { name: "varchar", limit: 255 },
        text:        { name: "text", limit: 65535 },
        integer:     { name: "int", limit: 4 },
        float:       { name: "float" },
        decimal:     { name: "decimal" },
        datetime:    { name: "datetime" },
        timestamp:   { name: "timestamp" },
        time:        { name: "time" },
        date:        { name: "date" },
        binary:      { name: "blob", limit: 65535 },
        boolean:     { name: "tinyint", limit: 1 },
        json:        { name: "json" },
      }
    
      # Maps logical Rails types to MySQL-specific data types.
      def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = nil)
        sql = case type.to_s
        when 'integer'
          integer_to_sql(limit)
        when 'text'
          text_to_sql(limit)
        when 'blob'
          binary_to_sql(limit)
        when 'binary'
          if (0..0xfff) === limit
            "varbinary(#{limit})"
          else
            binary_to_sql(limit)
          end
        else
          super(type, limit, precision, scale)
        end
    
        sql << ' unsigned' if unsigned && type != :primary_key
        sql
      end    
    
    # and integer ...
    
      def integer_to_sql(limit) # :nodoc:
        case limit
        when 1; 'tinyint'
        when 2; 'smallint'
        when 3; 'mediumint'
        when nil, 4; 'int'
        when 5..8; 'bigint'
        else raise(ActiveRecordError, "No integer type has byte size #{limit}")
        end
      end
    
     # and text ..
    
      def text_to_sql(limit) # :nodoc:
        case limit
        when 0..0xff;               'tinytext'
        when nil, 0x100..0xffff;    'text'
        when 0x10000..0xffffff;     'mediumtext'
        when 0x1000000..0xffffffff; 'longtext'
        else raise(ActiveRecordError, "No text type has byte length #{limit}")
        end
      end
    
    # and binary ...
    
        def binary_to_sql(limit) # :nodoc:
          case limit
          when 0..0xff;               "tinyblob"
          when nil, 0x100..0xffff;    "blob"
          when 0x10000..0xffffff;     "mediumblob"
          when 0x1000000..0xffffffff; "longblob"
          else raise(ActiveRecordError, "No binary type has byte length #{limit}")
          end
        end
    

    на super на type_to_sql метод

    #activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
      def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
        type = type.to_sym if type
        if native = native_database_types[type]
          column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup
    
          if type == :decimal # ignore limit, use precision and scale
            scale ||= native[:scale]
    
            if precision ||= native[:precision]
              if scale
                column_type_sql << "(#{precision},#{scale})"
              else
                column_type_sql << "(#{precision})"
              end
            elsif scale
              raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified"
            end
    
          elsif [:datetime, :time].include?(type) && precision ||= native[:precision]
            if (0..6) === precision
              column_type_sql << "(#{precision})"
            else
              raise(ActiveRecordError, "No #{native[:name]} type has precision of #{precision}. The allowed range of precision is from 0 to 6")
            end
          elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit])
            column_type_sql << "(#{limit})"
          end
    
          column_type_sql
        else
          type.to_s
        end
      end