ANNAIマガジン
この記事の目次

前回の記事ではノードと、ノードが標準で持っているタイトルや本文のデータがどのような構造になっているか見てみました。

今回は管理画面からカスタムフィールドを追加し、それらのデータ構造を見ていきましょう。

 

「ページ」ノードにカスタムフィールドを追加する

それでは、 /admin/structure/types/manage/page/fields から「基本ページ」にフィールドをいくつか追加していきます。

まず、テキストフィールドを追加してみましょう。以下のように設定して「保存して次へ」ボタンを押します。

  • 「新しいフィールドの追加」:テキスト(プレーン)を選択
  • 「ラベル」: custom_text
add textfield 1

「許容する値の数」を「無制限」に設定して「フィールド設定を保存」を押します。

add textfield 2

続けて、同様に /admin/structure/types/manage/page/fields から真偽値フィールドを追加します。以下のように設定して「保存して次へ」ボタンを押します。

  • 「新しいフィールドの追加」:真偽値を選択
  • 「ラベル」: custom_boolean
add boolean field 1

「許容する値の数」を「1」に設定して「フィールド設定を保存」を押します。

add boolean field 2

これで、デフォルトから存在する「本文」の他に2つのフィールドが追加されました。

show fields of page

カスタムフィールドのデータ構造

この状態で、再度DBのテーブル一覧を見てみます。

MariaDB [drupal]> show tables;
+-------------------------------------+
| Tables_in_drupal                    |
+-------------------------------------+
| block_content                       |

...

| node__field_custom_boolean          |
| node__field_custom_text             |
| node_revision__field_custom_boolean |
| node_revision__field_custom_text    |

...

+-------------------------------------+
74 rows in set (0.00 sec)

テーブルが4つ増えていることがわかります。

それでは、ノードの編集画面を開き追加したフィールドに値を入れて保存してみましょう。

まず、追加したカスタムフィールドに以下のように値を入れて保存します。

create node r1

再度ノードの編集画面を開き、次は以下のように値を入れて保存します。

create node r2

それでは、データの構造と実際のデータを見ていきましょう。

まずは追加したテキストフィールドのデータ構造を見てみます。

MariaDB [drupal]> describe node__field_custom_text;
+-------------------------+------------------+------+-----+---------+-------+
| Field                   | Type             | Null | Key | Default | Extra |
+-------------------------+------------------+------+-----+---------+-------+
| bundle                  | varchar(128)     | NO   | MUL |         |       |
| deleted                 | tinyint(4)       | NO   | PRI | 0       |       |
| entity_id               | int(10) unsigned | NO   | PRI | NULL    |       |
| revision_id             | int(10) unsigned | NO   | MUL | NULL    |       |
| langcode                | varchar(32)      | NO   | PRI |         |       |
| delta                   | int(10) unsigned | NO   | PRI | NULL    |       |
| field_custom_text_value | varchar(255)     | NO   |     | NULL    |       |
+-------------------------+------------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

MariaDB [drupal]> describe node_revision__field_custom_text;
+-------------------------+------------------+------+-----+---------+-------+
| Field                   | Type             | Null | Key | Default | Extra |
+-------------------------+------------------+------+-----+---------+-------+
| bundle                  | varchar(128)     | NO   | MUL |         |       |
| deleted                 | tinyint(4)       | NO   | PRI | 0       |       |
| entity_id               | int(10) unsigned | NO   | PRI | NULL    |       |
| revision_id             | int(10) unsigned | NO   | PRI | NULL    |       |
| langcode                | varchar(32)      | NO   | PRI |         |       |
| delta                   | int(10) unsigned | NO   | PRI | NULL    |       |
| field_custom_text_value | varchar(255)     | NO   |     | NULL    |       |
+-------------------------+------------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

サマリーとテキストフォーマットがない以外は本文(body)とほぼ同じ構造ですね。

リビジョンが別テーブルになっているのも同じです。

次に真偽値フィールドのデータ構造を見てみます。

MariaDB [drupal]> describe node__field_custom_boolean;
+----------------------------+------------------+------+-----+---------+-------+
| Field                      | Type             | Null | Key | Default | Extra |
+----------------------------+------------------+------+-----+---------+-------+
| bundle                     | varchar(128)     | NO   | MUL |         |       |
| deleted                    | tinyint(4)       | NO   | PRI | 0       |       |
| entity_id                  | int(10) unsigned | NO   | PRI | NULL    |       |
| revision_id                | int(10) unsigned | NO   | MUL | NULL    |       |
| langcode                   | varchar(32)      | NO   | PRI |         |       |
| delta                      | int(10) unsigned | NO   | PRI | NULL    |       |
| field_custom_boolean_value | tinyint(4)       | NO   |     | NULL    |       |
+----------------------------+------------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

MariaDB [drupal]> describe node_revision__field_custom_boolean;
+----------------------------+------------------+------+-----+---------+-------+
| Field                      | Type             | Null | Key | Default | Extra |
+----------------------------+------------------+------+-----+---------+-------+
| bundle                     | varchar(128)     | NO   | MUL |         |       |
| deleted                    | tinyint(4)       | NO   | PRI | 0       |       |
| entity_id                  | int(10) unsigned | NO   | PRI | NULL    |       |
| revision_id                | int(10) unsigned | NO   | PRI | NULL    |       |
| langcode                   | varchar(32)      | NO   | PRI |         |       |
| delta                      | int(10) unsigned | NO   | PRI | NULL    |       |
| field_custom_boolean_value | tinyint(4)       | NO   |     | NULL    |       |
+----------------------------+------------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

追加したテキストフィールドのテーブルと真偽値フィールドのテーブル構造が、一番下のカラム以外は全て同一であることがわかると思います。

今回はテキストと真偽値の例ですが、テキストエリア・日付・URLといった別のデータ型でも同じルールでデータ構造が自動的に決定されます。

では、データも見てみましょう。

MariaDB [drupal]> select bundle,entity_id,revision_id,delta,field_custom_text_value from node__field_custom_text;
+--------+-----------+-------------+-------+-------------------------+
| bundle | entity_id | revision_id | delta | field_custom_text_value |
+--------+-----------+-------------+-------+-------------------------+
| page   |         1 |           4 |     0 | テキスト1.1             |
| page   |         1 |           4 |     1 | テキスト2.1             |
+--------+-----------+-------------+-------+-------------------------+
2 rows in set (0.00 sec)

MariaDB [drupal]> select bundle,entity_id,revision_id,delta,field_custom_text_value from node_revision__field_custom_text;
+--------+-----------+-------------+-------+-------------------------+
| bundle | entity_id | revision_id | delta | field_custom_text_value |
+--------+-----------+-------------+-------+-------------------------+
| page   |         1 |           3 |     0 | テキスト1               |
| page   |         1 |           3 |     1 | テキスト2               |
| page   |         1 |           4 |     0 | テキスト1.1             |
| page   |         1 |           4 |     1 | テキスト2.1             |
+--------+-----------+-------------+-------+-------------------------+
4 rows in set (0.00 sec)

MariaDB [drupal]> select bundle,entity_id,revision_id,delta,field_custom_boolean_value from node__field_custom_boolean;
+--------+-----------+-------------+-------+----------------------------+
| bundle | entity_id | revision_id | delta | field_custom_boolean_value |
+--------+-----------+-------------+-------+----------------------------+
| page   |         1 |           4 |     0 |                          0 |
+--------+-----------+-------------+-------+----------------------------+
1 row in set (0.00 sec)

MariaDB [drupal]> select bundle,entity_id,revision_id,delta,field_custom_boolean_value from node_revision__field_custom_boolean;
+--------+-----------+-------------+-------+----------------------------+
| bundle | entity_id | revision_id | delta | field_custom_boolean_value |
+--------+-----------+-------------+-------+----------------------------+
| page   |         1 |           3 |     0 |                          1 |
| page   |         1 |           4 |     0 |                          0 |
+--------+-----------+-------------+-------+----------------------------+
2 rows in set (0.00 sec)

テキストフィールドの方は複数の登録を可能に設定しましたので、deltaが0と1のデータが1件ずつ入っています。

まとめ

ノードにカスタムフィールドを追加すると、

  • ノードにフィールドを追加すると、 "node__{fieldname}" と "node_revision__{fieldname}" という2つのテーブルが生成される
  • この2つテーブルの構造は全く同一である
  • テーブルには bundle, deleted, entity_id, revision_id, langcode, delta という全フィールドで共通のカラムがあり、"{fieldname}_value" というカラムも必ず定義される
  • フィールドに対して複数の値の入力を許可すると、deltaの値が0,1...のようにindexとして登録される
  • "node_revision__{fieldname}" には過去の全てのリビジョンのデータが格納され、 "node__{fieldname}" には最新のリビジョンのデータのみが格納される

というルールでデータ構造が自動的に定義されます。

このように一定のルールや命名規則に従いデータ構造を自動生成することによって、Viewsによるデータの抽出や加工、API化などの後処理などが共通化され、様々なフォーマットによる柔軟なコンテンツ配信が可能になります。

 
フッターの採用情報
 
Yoshikazu Aoyamaの写真

この記事を書いた人: Yoshikazu Aoyama

昔は回線交換やL2/L3のプロトコルスタックの開発をしてました。その後、組み込みLinuxやJava/Ruby on RailsなどのWebシステム開発などを経て現職。
インフラからDrupalのモジュール開発、Drupal以外の開発までなんでもやります。
普段は札幌で猫と一緒にリモートワークしています。 好きなモジュールは Restful Web Services と Rules

関連コンテンツ