Railsカラム型のドキュメントはありますか?


181

このページにある単純なタイプのリスト以上のものを探しています

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

しかし、これらのフィールドを実際に定義しているドキュメントはありますか?

具体的には:

  • 違いは何だ:stringとは:text
  • :float:decimal
  • 何の際立った特徴があり:time:timestamp:datetime

これらのタイプのニュアンスはどこかに文書化されていますか?

編集:DBプラットフォーム実装のポイントは、私が尋ねようとしている質問とは無関係です。 たとえば、:datetimeRailsのドキュメントで意図された意味が定義されていない場合、対応する列タイプを選択するときに、db-adapter-writersは何を行うのでしょうか。


1
言葉の私の選択を言い訳、これらの種類、何をしているものは、と呼ばれますか?同様に、それらはフィールドまたは属性または何ですか。私は他を探していたもの以外の:string:text、私はこれ以外を見つけることができませんでした。それで、私は将来の参考のためにただ考えていました。
l1zZY 2015

2
@ l1zZY、あなたが探しているかもしれない用語は「データ型」です。
thatpaintingelephant 16

回答:


397

個人的な経験から構築されたガイドライン:

  • 文字列
    • 255文字に制限(DBMSに依存)
    • 短いテキストフィールド(名前、電子メールなど)に使用します
  • テキスト
    • 無制限の長さ(DBMSに依存)
    • コメント、ブログ投稿などに使用します。一般的な経験則:textareaを介してキャプチャされる場合は、Textを使用します。テキストフィールドを使用した入力には、文字列を使用します。
  • 整数
    • 整数
  • フロート
    • 浮動小数点精度で格納された10進数
    • 精度は固定されているため、一部の計算で問題が発生する可能性があります。不正確な丸めのため、一般に数学演算には適していません。
  • 10進数:
    • 計算に必要なものに応じて異なる精度で保存された10進数。正確である必要がある計算にこれらを使用します
    • floatとdecimalsの違いの例と詳細な説明については、この投稿を参照してください。
  • ブール
    • true / false属性(つまり、オン/オフなど、2つの状態のみを持つもの)を格納するために使用します。
  • バイナリ
    • 画像、動画、その他のファイルを、BLOBと呼ばれるデータのチャンクに元の生の形式で保存するために使用します
  • :primary_key
    • このデータ型は、Railsが選択したデータベースに必要な主キーデータ型(serial primary keypostgreSQLなど)に変換されるプレースホルダーです。その使用はやや複雑であり、推奨されません。
    • 代わりに、モデルと移行の制約を(オプションvalidates_uniqueness_ofと同様に)使用して、独自のフィールドの1つで主キー機能をシミュレートします。add_index:unique => true
  • 日付
    • 日付(年、月、日)のみを格納します
  • 時間
    • 時間(時間、分、秒)のみを格納します
  • 日時
    • 日付と時刻の両方を保存します
  • タイムスタンプ
    • 日付と時刻の両方を保存します
    • 注:Railsでは、TimestampとDateTimeはどちらも同じ意味です(日付と時刻の両方を格納するにはどちらかのタイプを使用します)。両方が存在する理由のTL; DRの説明については、下の段落をお読みください。

これらは、しばしば混乱が存在するタイプです。これがお役に立てば幸いです。これらに関する公式のドキュメントがない理由は本当にわかりません。また、あなたが参照したこれらのデータベースアダプターは、R​​ailsを作成したのと同じ人が作成したものだと思います。お役に立てれば!

注:両方の存在:DateTime:Timestamp、私が見つけることができるものからは、ほとんどのデータベースシステムとの互換性のためのRailsによって含まれます。たとえば、MySQLのTIMESTAMPデータ型はUNIXタイムスタンプとして保存されます。有効範囲は1970〜2038で、時間は最後のエポックから経過した秒数として格納されます。これは標準的なものと考えられますが、実際にはシステムによって異なる場合があります。相対時間は、データベースを持っていることは良いことではありませんでしたことを認識し、MySQLは、後に導入されたDATETIMEサイズの増加を犠牲にし、年、月、日、時、分、秒にすべての桁を保存するデータ型を、。のTIMESTAMPデータ型は、下位互換性のために保持されていました。他のデータベースシステムも同様の進化を遂げました。Railsは複数の標準が存在することを認識し、両方へのインターフェースを提供しました。ただし、Rails ActiveRecordのデフォルトは、MySqlに格納されているUTC日付:Timestampとデフォルトの両方なので、Railsプログラマーにとって機能上の違いはありません。これらは、2つを区別したいユーザーがそうできるように存在します。(より詳細な説明については、この SOの回答を参照してください)。:DateTimeDATETIME


21
@aguazalesはすばらしい記事です。Railsのドキュメントにこのようなものがないのは大きな見落としのようです。
Grant Birchmeier、2012

ありがとう:)そして、私は完全に同意します。ActiveRecordとそのデータ型はRailsにとって非常に重要です。なぜこれが標準のドキュメントではないのでしょうか。
アグアザール

2
テキストの長さは常に無制限ではありません-MySQLでは約16kbに制限されています。16kb以上が必要な場合は、MEDIUMTEXTおよびLONGTEXTデータベースタイプがあります。
ヘギン2014

3
これは、Rails移行データ型– MySql – Postgresql – SQLiteの優れたソースでもあります。私はそれがデータベース固有であることを知っていますが、実際の実装を知っていることは、railsデータベースのタイプを理解するときに依然として役立ちます。
2014

1
100%確信はありませんが、Nateのリソースはここに再投稿さたと思います
アグアザレス2017

10

私が見つけたRailsマスターブランチのソースコードから:

抽象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

方法supertype_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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.