概要
Salesforce と連携したアプリケーションの開発をする際に、便利な設定を見つけたので記事にしました。
Salesforce のデータを Heroku Connect によって Heroku Postgres とデータ同期をすると salesforce
というスキーマが作成されます。
今までは Eloquent モデルにテーブル名を指定する際に、下記のようにスキーマ名を入れていましたが、これを省略する方法を紹介します。
use Illuminate\Database\Eloquent\Model;
class SalesforceTest extends Model {
protected $table = 'salesforce.test__c';
}
環境
- Laravel 9
- Heroku Postgres
- Heroku Connect
結論
こちらの Heroku Connect のドキュメントにスキーマ名を省略する方法が載っていますが、別途SQLを発行する必要があります。
SET search_path TO salesforce,public;
この記事では Laravel の設定で上記と同じ状態にします。
結論から言いますと Laravel プロジェクトの設定ファイルの config/database.php
内にある search_path
もしくは schema
の項目に salesforce
を追加すると完成です。
'connections' => [
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
- 'search_path' => 'public',
+ 'search_path' => ['public', 'salesforce'],
'sslmode' => 'prefer',
]
]
解説
ここからは Laravel 内での挙動を解説します。
Laravel が Postgres の DB にSQLを発行する際に vendor/laravel/framework/src/Illuminate/Database/Connectors/PostgresConnector.php
の configureSearchPath
関数が実行されます。
/**
* Set the "search_path" on the database connection.
*
* @param \PDO $connection
* @param array $config
* @return void
*/
protected function configureSearchPath($connection, $config)
{
if (isset($config['search_path']) || isset($config['schema'])) {
$searchPath = $this->quoteSearchPath(
$this->parseSearchPath($config['search_path'] ?? $config['schema'])
);
$connection->prepare("set search_path to {$searchPath}")->execute();
}
}
この $config
には config/database.php
の pgsql
の内容が入っています。
search_path
がなければ schema
が参照されるようになっているため、両方設定されている場合は search_path
が優先されます。
また quoteSearchPath
関数と parseSearchPath
関数によって整形されるため、配列とカンマ区切りの設定に対応しています。
'search_path' => ['public', 'salesforce']
'search_path' => 'public, salesforce'
$connection->prepare("set search_path to {$searchPath}")->execute();
により search_path
が設定されます。
最後に
もし環境ごとにスキーマ名が変わる場合は、環境変数で制御するようにできます。
DB_SCHEMA=stgpublic
DB_SCHEMA_SALESFORCE=stgsalesforce
'connections' => [
'pgsql' => [
'search_path' => [env('DB_SCHEMA', 'public'), env('DB_SCHEMA_SALESFORCE', 'salesforce')],
]
]
同じ悩みを抱えている方の助けになれば嬉しいです。
私がコードを読んで解釈した内容ですので、もし間違っている箇所がありましたらご指摘いただけますと幸いです。