Railsで使うデータベース上の特別な意味を持つ列名

Railsをかじっていると、"id"やら、"created_at"やら便利なカラムの存在が気になってきました。
ほかにも色々と便利なカラムがあるけど、知らないから損をしているんじゃないかと。
で、調べてみた。
MagicFieldNames in Ruby on Rails
なんか、いっぱいある。

  • created_at
  • created_on
  • updated_at
  • updated_on
  • lock_version
  • type
  • id
  • #{table_name}_count
  • position
  • parent_id
  • lft
  • rgt

実験

とりあえず、Timestampingと題してある、

  • created_at
  • created_on
  • updated_at
  • updated_on

から調べてみよう。
適当にプロジェクトと、モデルを作成。

>rails MagicField
(略)
>cd MagicField
>ruby script\generate model diary
(略)

んで、migration作成。(MySQL、config/database.ymlなど適当にセットアップ)
db/migrate/001_create_diaries.rb

(略)
def self.up
  create_table :diaries do |t|
    t.column :title, :string
    t.column :text, :text
    t.column :created_at, :datetime
    t.column :created_on, :datetime
    t.column :updated_at, :datetime
    t.column :updated_on, :datetime
  end
end
(略)

で、migrate

>rake db:migrate

テーブルを確認。MySQLのプロンプトから

mysql> desc diaries;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| title      | varchar(255) | YES  |     | NULL    |                |
| text       | text         | YES  |     | NULL    |                |
| created_at | datetime     | YES  |     | NULL    |                |
| created_on | datetime     | YES  |     | NULL    |                |
| updated_at | datetime     | YES  |     | NULL    |                |
| updated_on | datetime     | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

動くものが見たいので、Scaffoldも作っちゃう。

>ruby script\generate scaffold diary

Scaffoldのままだと、フォームにcreated_at、created_on、updated_at、updated_onも含まれてしまうので、app/views/diaries/_form.rhtmlのTimestamping関係を削除。あと、Textのフォームが馬鹿でかいので調整。
調整後の、app/views/diaries/_form.rhtm全文。

<%= error_messages_for 'diary' %>

<!--[form:diary]-->
<p><label for="diary_title">Title</label><br/>
<%= text_field 'diary', 'title'  %></p>

<p><label for="diary_text">Text</label><br/>
<%= text_area 'diary', 'text', :rows => 5 %></p>
<!--[eoform:diary]-->

HTTPサーバ起動

>ruby script\server


で、書いてみる。


編集してみる。


"created"と"updated"は読んで字のごとく、作られた時刻と更新された時刻だ。
"at"と"on"の違いがわかりません。仕方ない、読むか。

  • created_on: date only
  • created_at: date and time
  • same for updated_at/updated_on fields

leeo: While this is a commonly held convention, I don’t see it referenced in the Rails source anywhere. More importantly, at/on doesn’t actually affect the value or type of data being stored. Rails simply throws a Time in there, which gets cast into a Date if so required by the schema.

むむ、スキーマがそう望むなら時間を含まない日付になる?
テーブルを変えてみよう。

>ruby script\generate migration change_on

db/migrate/002_change_on.rb

(略)
def self.up
  change_column(:diaries, :created_on, :date)
  change_column(:diaries, :updated_on, :date)
end
(略)

で、migrate

>rake migrate

diariesテーブルはこんな感じ。

mysql> desc diaries;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| title      | varchar(255) | YES  |     | NULL    |                |
| text       | text         | YES  |     | NULL    |                |
| created_at | datetime     | YES  |     | NULL    |                |
| created_on | date         | YES  |     | NULL    |                |
| updated_at | datetime     | YES  |     | NULL    |                |
| updated_on | date         | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

で、作成&編集。

なるほど。
逆に"at"を:dateにして実験。

mysql> desc diaries;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| title      | varchar(255) | YES  |     | NULL    |                |
| text       | text         | YES  |     | NULL    |                |
| created_at | date         | YES  |     | NULL    |                |
| created_on | date         | YES  |     | NULL    |                |
| updated_at | date         | YES  |     | NULL    |                |
| updated_on | date         | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+


動いた…
"at"と"on"の違いは、それを人が読んだ時にどう感じるかで、実装上は同じ処理なのだろうか…