項目用のカラムをモジュールのメインテーブルとは別のテーブルに作成する方法

すっかり寒くなってしまい、去年冬物コートを捨てたことを思い出して慌てて買いに行ったエンジニアリングチームの川合(@Ricckn)です。
今年は比較的暖かかったのですが、夜の冷え込みが完全に冬のそれになりましたね。みなさまも風邪などには気をつけてください。

大量のフィールド、MySQLの1テーブルに乗らない問題

CRMでデータを管理する際、特に別のシステムから移行する場合などに大量の項目を登録するケースがあると思います。
しかし、あまりに多い項目数になるとMySQLのカラム数の制限により、同一テーブルにカラムを増やすことができなくなってしまいます。

※参考(https://dev.mysql.com/doc/refman/5.6/ja/column-count-limit.html

F-RevoCRMでは、項目自体の管理をvtiger_fieldというテーブルを利用して管理しているため、テーブルを複数に分けることが可能です。

項目作成のスクリプト

例えば、新規フィールドをモジュールに追加する際には、標準のクラスを使った場合以下のようなスクリプトになります。
こちらは、

// 会社の特徴
$field = new Vtiger_Field();
$field->name = 'field_name';
$field->table = 'vtiger_account';
$field->column = $field->name;
$field->columntype = 'varchar(255)';
$field->uitype = 1;
$field->typeofdata = 'V~O';
$field->masseditable = 1;
$field->quickcreate = 0;
$field->summaryfield = 0;
$field->label = '会社の特徴';
$blockInstance->addField($field);

// 旧社内管理No
$field = new Vtiger_Field();
$field->name = 'field_name2';
$field->table = 'vtiger_account_sub';
$field->column = $field->name;
$field->columntype = 'varchar(255)';
$field->uitype = 1;
$field->typeofdata = 'V~O';
$field->masseditable = 1;
$field->quickcreate = 0;
$field->summaryfield = 0;
$field->label = '旧社内管理No';
$blockInstance->addField($field);

Vtiger_Fieldクラスには、$field->tableという値があるので、ここにテーブル名を入れることで、指定したテーブルに項目を追加することが可能です。
※「旧社内管理No」フィールドのケース

しかし、このままではテーブル自体が作成されていない為、以下のメソッドを事前に流しておく必要があります。
「会社の特徴」フィールドの後のスクリプトは、以下のようになります。

// 会社の特徴
$field = new Vtiger_Field();
$field->name = 'field_name';
$field->table = 'vtiger_account';
$field->column = $field->name;
$field->columntype = 'varchar(255)';
$field->uitype = 1;
$field->typeofdata = 'V~O';
$field->masseditable = 1;
$field->quickcreate = 0;
$field->summaryfield = 0;
$field->label = '会社の特徴';
$blockInstance->addField($field);

$module = Vtiger_Module::getInstance('Accounts');
// テーブルを作成
$module->initTables('vtiger_account_sub', 'accountid');

// 旧社内管理No
$field = new Vtiger_Field();
$field->name = 'field_name2';
$field->table = 'vtiger_account_sub';
$field->column = $field->name;
$field->columntype = 'varchar(255)';
$field->uitype = 1;
$field->typeofdata = 'V~O';
$field->masseditable = 1;
$field->quickcreate = 0;
$field->summaryfield = 0;
$field->label = '旧社内管理No';
$blockInstance->addField($field);

$module->initTablesによって、モジュールで管理するテーブルを作成できます。
第1引数はテーブル名。
第2引数は、KeyとなるIDなので、慣例的にモジュールのメインのIDと一致させたほうが良いでしょう(もしくは、同等なcrmidと書くのが良いと思います)

データを作れば良いわけではありません!

テーブルができた、vtiger_fieldにも項目の情報が登録された!
でもこれだけではありません。

frevocrm_root/modules/{MODULE}/{MODULE}.phpには以下のような記述があり、レポート作成時にどのテーブルをどのキーでJOINするかと言った際に利用しています。
その為、以下のように追記する必要があります。

class Accounts extends CRMEntity {
	var $log;
	var $db;
	var $table_name = "vtiger_account";
	var $table_index= 'accountid';
	var $tab_name = Array('vtiger_crmentity','vtiger_account','vtiger_accountbillads','vtiger_accountshipads','vtiger_accountscf', 'vtiger_account_sub');
	var $tab_name_index = Array('vtiger_crmentity'=>'crmid','vtiger_account'=>'accountid','vtiger_accountbillads'=>'accountaddressid','vtiger_accountshipads'=>'accountaddressid','vtiger_accountscf'=>'accountid', 'vtiger_account_sub' => 'accountid');

見ずらいですが、

  • $tab_nameの配列にテーブル名を追加
  • $tab_name_indexにtablename => keyとなるように連想配列を追加

ここまでが標準で必要な部分となります!

まとめ

もちろんSQLを書いて、CREATE TABLEを行っても良いわけですが、このように便利なメソッドが用意されていますので、積極的に使っていければと思います。
知っていることで、SQLを書くことによるミスを減らせますし、自動化も楽になります。

また、こちらのメソッドの注意点ですが、キーとなる第2引数のカラムにindexが付与されません
こちらは手動で登録する必要がありますが、弊社としてもバージョンアップで自動適用のパッチを書ければと思います。(毎回やることになるので・・・)

それでは次回の記事で!

ご質問・お問い合わせはこちら

メールフォームへ