Herokuにcandycaneをインストールする2 candycaneを魔改造する
もうPHPのpaasならAppFogでも良かったんじゃないかと思い始めるも、railsも勉強したいので引き続きHerokuやります。
Herokuにしろ、AppFogにしろ、Webサーバー上にファイルの保存ができない。
デプロイにgitを使ってるから今のところしょうがないのかもしれないけど。
参考情報:知っておきたい!Herokuを使う上では当たり前?の16の常識 常識2. Dynoにファイルアップロードしても再起動時に消える
candycaneでは、チケットに添付したファイルがこれに相当するので、
Herokuの再起動もしくはソースコードをpushすると、添付ファイルが消えてしまう。
チケットを活用するにあたってこれはちと辛い。
そこで、「チケットの添付ファイルそのものをSQLの中にデータとしてブッコんじゃうんでヨロシク!」魔改造。
あくまでも魔改造なので自己責任でお使いください。
attachmentsというテーブルがチケット内容(2014.02.03修正)添付ファイルのレコードとなっているようなので、
attachmentsテーブルにcontentというカラム名(TEXT)を追加してそこにデータを入れてしまうのだ。
candycaneの初期設定が終わってる場合(既にテーブルが作られている場合)はSQLのカラム追加は自力で行う。
(このためにphpPgAdminをインストールしたかったw)
candycaneの初期設定が終わっていない場合(テーブルが作られていない場合)なら、テーブルの雛形ファイル
mysql.sql
pgsql.sql
postgres.sql
に事前にカラム追加しておけばテーブル作成時に自動的に作られると思う(未実践)。
ソースコードの改造箇所はたった3箇所。
app/Config/Schema/schema.php
public $attachments = array( ...中略 'description' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_unicode_ci', 'charset' => 'utf8'), >>>追加 'content' => array('type' => 'text', 'null' => true, 'default' => NULL, 'collate' => 'utf8_unicode_ci', 'charset' => 'utf8'), >>>追加終わり 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)), 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_unicode_ci', 'engine' => 'InnoDB') );
app/Model/Attachment.php
public function beforeSave($options = array()) { parent::beforeSave($options); if (!empty($this->data[$this->alias]['temp_file']) && !empty($this->data[$this->alias]['filesize'])) { $this->data[$this->alias]['disk_filename'] = $this->create_disk_filename($this->data[$this->alias]['temp_file'], $this->data[$this->alias]['filename']); >>>追加 $this->data[$this->alias]['content'] = base64_encode( @file_get_contents($this->data[$this->alias]['temp_file']) ); >>>追加終わり $this->log("saving '{$this->diskfile()}'", LOG_DEBUG); @copy($this->data[$this->alias]['temp_file'], $this->diskfile()); ...中略 return true; } public function diskfile() { >>>置き換え $filepath = $this->storage_path . $this->data[$this->alias]['disk_filename']; if(file_exists($filepath)==false) { @file_put_contents( $filepath, @base64_decode($this->data[$this->alias]['content']) ); } >>>置き換え終わり return $filepath; }
そんでもってHerokuにpushしてデプロイして終わり。
これで、Herokuが再起動してファイルが消されたとしても、データベースから復元できるようになる。
が、魔改造たる所以、でかい画像を添付したりするとデータベースのディスク使用量が暴力的に増える。
2013年12月現在、HerokuのpostgresSQL(無料プラン)では、使用制限がディスク容量ではなくレコード数(Enforced row limits of 10,000 rows for hobby-dev)のようなので、なんとか逃げきれる、かも。