Enviar búsqueda
Cargar
Heroku connect 苦肉の四苦八苦
•
Descargar como PPTX, PDF
•
1 recomendación
•
3,260 vistas
Hideki Ohkubo
Seguir
Heroku Connectを、モダンWebフレームワーク(Rails)で扱った際のノウハウをまとめました。
Leer menos
Leer más
Ingeniería
Denunciar
Compartir
Denunciar
Compartir
1 de 35
Descargar ahora
Recomendados
Spring boot 勉強会
Spring boot 勉強会
太志郎 遠藤
Webアプリを並行開発する際のマイグレーション戦略
Webアプリを並行開発する際のマイグレーション戦略
Takayuki Shimizukawa
シングルサインオンの歴史とSAMLへの道のり
シングルサインオンの歴史とSAMLへの道のり
Shinichi Tomita
オープンソースのAPIゲートウェイ Kong ご紹介
オープンソースのAPIゲートウェイ Kong ご紹介
briscola-tokyo
基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装
Masatoshi Tada
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
NTT DATA Technology & Innovation
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
Masatoshi Tada
RESTfulとは
RESTfulとは
星影 月夜
Recomendados
Spring boot 勉強会
Spring boot 勉強会
太志郎 遠藤
Webアプリを並行開発する際のマイグレーション戦略
Webアプリを並行開発する際のマイグレーション戦略
Takayuki Shimizukawa
シングルサインオンの歴史とSAMLへの道のり
シングルサインオンの歴史とSAMLへの道のり
Shinichi Tomita
オープンソースのAPIゲートウェイ Kong ご紹介
オープンソースのAPIゲートウェイ Kong ご紹介
briscola-tokyo
基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装
Masatoshi Tada
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
NTT DATA Technology & Innovation
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
Masatoshi Tada
RESTfulとは
RESTfulとは
星影 月夜
Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話
KEISUKE KONISHI
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
Y Watanabe
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
NTT Communications Technology Development
JP1/AJS2オペレータ勉強会
JP1/AJS2オペレータ勉強会
mizuky fujitani
ビッグデータ処理データベースの全体像と使い分け
ビッグデータ処理データベースの全体像と使い分け
Recruit Technologies
Apache OpenWhiskで実現するプライベートFaaS環境 #tjdev
Apache OpenWhiskで実現するプライベートFaaS環境 #tjdev
Yahoo!デベロッパーネットワーク
お前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのか
Kousuke Ebihara
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
Atsushi Nakamura
SREチームとしてSREしてみた話
SREチームとしてSREしてみた話
Yahoo!デベロッパーネットワーク
DDD sample code explained in Java
DDD sample code explained in Java
増田 亨
爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話
Kentaro Yoshida
OAuth2.0によるWeb APIの保護
OAuth2.0によるWeb APIの保護
Naohiro Fujie
REST API のコツ
REST API のコツ
pospome
マイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPC
disc99_
Spring CloudとZipkinを利用した分散トレーシング
Spring CloudとZipkinを利用した分散トレーシング
Rakuten Group, Inc.
テストコードの DRY と DAMP
テストコードの DRY と DAMP
Yusuke Kagata
ログ+メトリック+トレースの組み合わせで構築する一元的なオブザーバビリティ
ログ+メトリック+トレースの組み合わせで構築する一元的なオブザーバビリティ
Elasticsearch
日本語テストメソッドについて
日本語テストメソッドについて
kumake
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
shinjiigarashi
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
Ryuji Tsutsui
Rubyist のフィリピン留学
Rubyist のフィリピン留学
Hideki Ohkubo
10年後になくなる仕事 / Jobs which will disappear 10 years later
10年後になくなる仕事 / Jobs which will disappear 10 years later
Hideki Ohkubo
Más contenido relacionado
La actualidad más candente
Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話
KEISUKE KONISHI
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
Y Watanabe
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
NTT Communications Technology Development
JP1/AJS2オペレータ勉強会
JP1/AJS2オペレータ勉強会
mizuky fujitani
ビッグデータ処理データベースの全体像と使い分け
ビッグデータ処理データベースの全体像と使い分け
Recruit Technologies
Apache OpenWhiskで実現するプライベートFaaS環境 #tjdev
Apache OpenWhiskで実現するプライベートFaaS環境 #tjdev
Yahoo!デベロッパーネットワーク
お前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのか
Kousuke Ebihara
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
Atsushi Nakamura
SREチームとしてSREしてみた話
SREチームとしてSREしてみた話
Yahoo!デベロッパーネットワーク
DDD sample code explained in Java
DDD sample code explained in Java
増田 亨
爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話
Kentaro Yoshida
OAuth2.0によるWeb APIの保護
OAuth2.0によるWeb APIの保護
Naohiro Fujie
REST API のコツ
REST API のコツ
pospome
マイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPC
disc99_
Spring CloudとZipkinを利用した分散トレーシング
Spring CloudとZipkinを利用した分散トレーシング
Rakuten Group, Inc.
テストコードの DRY と DAMP
テストコードの DRY と DAMP
Yusuke Kagata
ログ+メトリック+トレースの組み合わせで構築する一元的なオブザーバビリティ
ログ+メトリック+トレースの組み合わせで構築する一元的なオブザーバビリティ
Elasticsearch
日本語テストメソッドについて
日本語テストメソッドについて
kumake
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
shinjiigarashi
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
Ryuji Tsutsui
La actualidad más candente
(20)
Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
JP1/AJS2オペレータ勉強会
JP1/AJS2オペレータ勉強会
ビッグデータ処理データベースの全体像と使い分け
ビッグデータ処理データベースの全体像と使い分け
Apache OpenWhiskで実現するプライベートFaaS環境 #tjdev
Apache OpenWhiskで実現するプライベートFaaS環境 #tjdev
お前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのか
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
SREチームとしてSREしてみた話
SREチームとしてSREしてみた話
DDD sample code explained in Java
DDD sample code explained in Java
爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話
OAuth2.0によるWeb APIの保護
OAuth2.0によるWeb APIの保護
REST API のコツ
REST API のコツ
マイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPC
Spring CloudとZipkinを利用した分散トレーシング
Spring CloudとZipkinを利用した分散トレーシング
テストコードの DRY と DAMP
テストコードの DRY と DAMP
ログ+メトリック+トレースの組み合わせで構築する一元的なオブザーバビリティ
ログ+メトリック+トレースの組み合わせで構築する一元的なオブザーバビリティ
日本語テストメソッドについて
日本語テストメソッドについて
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
Más de Hideki Ohkubo
Rubyist のフィリピン留学
Rubyist のフィリピン留学
Hideki Ohkubo
10年後になくなる仕事 / Jobs which will disappear 10 years later
10年後になくなる仕事 / Jobs which will disappear 10 years later
Hideki Ohkubo
Job-Hub 自由をつかめ(大人の事情ver)
Job-Hub 自由をつかめ(大人の事情ver)
Hideki Ohkubo
Heroku meetup#11(フル)
Heroku meetup#11(フル)
Hideki Ohkubo
Heroku meetup#11(lt)
Heroku meetup#11(lt)
Hideki Ohkubo
SendGrid on Job-Hub
SendGrid on Job-Hub
Hideki Ohkubo
おいしいherokuの使い方
おいしいherokuの使い方
Hideki Ohkubo
Cacooではじめるスタートアップ
Cacooではじめるスタートアップ
Hideki Ohkubo
Más de Hideki Ohkubo
(8)
Rubyist のフィリピン留学
Rubyist のフィリピン留学
10年後になくなる仕事 / Jobs which will disappear 10 years later
10年後になくなる仕事 / Jobs which will disappear 10 years later
Job-Hub 自由をつかめ(大人の事情ver)
Job-Hub 自由をつかめ(大人の事情ver)
Heroku meetup#11(フル)
Heroku meetup#11(フル)
Heroku meetup#11(lt)
Heroku meetup#11(lt)
SendGrid on Job-Hub
SendGrid on Job-Hub
おいしいherokuの使い方
おいしいherokuの使い方
Cacooではじめるスタートアップ
Cacooではじめるスタートアップ
Heroku connect 苦肉の四苦八苦
1.
Heroku Connect 苦肉の四苦八苦 大久保英樹
2.
自己紹介 • 名前:大久保英樹 • 職業:フリーランスプログラマ •
アカウント:@Oakbow7 • Herokuを扱う案件は8個目くらい? • Heroku Connectを扱う案件は4個目くらい?
3.
4U Lifecareとなでしこナース • フォー・ユー・ライフケア株式会社 •
https://4ulifecare.com/ • 医療系スタートアップ • 活用が限定されている医療人材を活かす • なでしこナース • https://nadeshikonurse.jp/ • 看護師向けの人材紹介サービス • 利用ユーザは看護師と病院・施設
4.
なでしこナース 病院・施設看護師 運営者 管理 管理 求人に応募 採用 Heroku Salesforce Salesforce
5.
なでしこナース Salesforce Partner Commyunity 病院・施設 Heroku 看護師 Salesfoce 運営 Heroku Connect
6.
今日お話しすること • Heroku Connectおさらい •
インピーダンスミスマッチその1 • Heroku と Salesforceの双方向同期で、IDをどうするか • インピーダンスミスマッチその2 • Salesforceのキャメルケース文化とRailsのスネークケース文化の ギャップの解消 • 現在の開発サイクル
7.
Heroku Connectおさらい Heroku Connect Heroku Postgres Salesfoce
8.
Heroku Connectおさらい • SalesforceのオブジェクトとHeroku
Postgresのテーブルを双 方向に同期してくれるアドオン • あくまでも主となるのはSalesforceオブジェクト。同期対象の オブジェクトとそのカラムをHeroku Connectコンソールで選 択すると、オブジェクトに対応したテーブルが自動生成される。 逆方向はできない • Heroku PostgreSQL -> Salesforceの同期時、Salesforceの ヴァリデーションに引っかかると同期エラーが起きる。
9.
Heroku Connectおさらい • テーブル作成はHeroku
Connectを介してしか行えない(フ レームワークのマイグレーション機能は原則そのまま使えな い) • Salesforce側のオブジェクト定義に依存するので、テーブル名、 カラム名やデータ型、データ長さは変更できない • 親と子どちらのレコードが先に同期されるか分からないので、 FK(外部参照制約)は使えない(貼ることは可能だが、FKエ ラーで同期失敗する) • サロゲートキーとしてIDカラムが生成されるが、Salesforce側 には同期されない
10.
Heroku Connectおさらい Heroku Connect Heroku Postgres Salesfoce Rails Railsの期待する データベーススキーマ(理想) Heroku Connectが作る データベーススキーマ(現実) Heroku
Postgres
11.
12.
Heroku Postgres Salesforce id sfid
← sfid mofid__c ⇄ mofID__c body__c ⇄ Body__c read__c ⇄ Read__c name ⇄ Name usermofid__c ⇄ UserMofId__c user__c ⇄ User__c conversationmofid__c ⇄ ConversationMofId__c conversation__c ⇄ Conversation__c createddate ⇄ CreatedDate systemmodstamp ⇄ SystemModStamp isdeleted ⇄ IsDeleted conversations__r__mofid__c user__r__mofid__c
13.
インピーダンスミスマッチその1 • PKをうまく同期できない • Salesforce側のPKはsfid •
Heroku Postgres側のPKはid
14.
インピーダンスミスマッチその1 • 結合にsfidを使用した場合 • Heroku側でレコードをInsert(sfidはNULL) •
InsertしたレコードをSalesforceに同期 • Salesforceでsfidを発番 • 更新したレコードをHeroku Postgresに同期 • PKを取得するために同期が二回必要 • HerokuにとってはSalesforceは所詮外部サービスなので、PKが外部 依存なのは開発する上で非常に不利(ローカルでどう開発する?テ ストは?CIで回せる?)
15.
インピーダンスミスマッチその1
16.
インピーダンスミスマッチその1解決編 • 結合に外部IDを使う(データ型は文字列型) • Heroku側でレコードをInsertするときはPostgreSQLのシーケンスを 突っ込む •
Salesforce側でレコードをInsertするときは、トリガでsfidを突っ込 む(1トランザクションで実行するよう頑張る) • idでもsfidでもない外部IDカラムexernal_id(ExternalId__c)を作り、 これを同期する。 • Heroku Postgres ではこのカラムをPKに指定(照合順序に注意) • Salesforceではこのカラムを外部IDとして設定する
17.
インピーダンスミスマッチその1解決編
18.
インピーダンスミスマッチその1解決編
19.
インピーダンスミスマッチその1解決編
20.
インピーダンスミスマッチその1解決編
21.
インピーダンスミスマッチその1解決編
22.
インピーダンスミスマッチその1解決編
23.
インピーダンスミスマッチその1解決編2
24.
インピーダンスミスマッチその2 • Salesforceはキャメルケース文化なので、オブジェクトや フィールド名は基本的にキャメルケース • カスタムオブジェクトやカスタムフィールドは、末尾に__cが 必ずつく(キモい) •
PostgreSQLのテーブル名やカラム名は大文字小文字を区別し ない(ので、小文字で表現される) • Railsはスネークケース文化 • レコードの作成日時、更新日時のフィールド名(カラム名)は それぞれ異なっている
25.
インピーダンスミスマッチその2 Rails(理想) PostgreSQL(現実) Salesforce updated_at
systemmodstamp SystemModStamp created_at createddate CreatedDate work_location_address1 worklocationaddress1__c WorkLocationAddress1__c contract_start_on contractstartdate__c ContractStartDate__c emergency_contact_details emergencycontactdetails__c EmergencyContactDetails__c id externalid ExternalId opportunity_technical_skill opportunitytechnicalskill__c OpportunityTechnicalSkill__c
26.
インピーダンスミスマッチその2解決編 Rails Model DB View (Updatable View) DB
Table
27.
インピーダンスミスマッチその2解決編
28.
インピーダンスミスマッチその2解決編
29.
インピーダンスミスマッチその2解決編
30.
インピーダンスミスマッチその2解決編
31.
インピーダンスミスマッチその2解決編
32.
インピーダンスミスマッチその2解決編 環境 環境変数 Salesforce
テーブル作成 カラム追加 カラム削除 ローカル開発 development なし される される される ローカルテス ト test なし される される される CI test なし される される される Review App production なし される される される ステージング production あり されない されない されない 本番 production あり されない されない されない
33.
ミスマッチを解消 Heroku Connect Heroku Postgres Salesfoce Rails Railsで扱いやすいように作った 更新可能ビュー Heroku Connectが作る salesforceスキーマ Heroku Postgres
34.
現在の開発サイクル Review App feature branchlocal
Circle CI master branch Staging Production Pull Request Auto Testing Merge Auto Deployment Promoting Create Review App
35.
現在の開発サイクル
Notas del editor
今回紹介する事例は、「なでしこナース」という看護師向け人材紹介サービスで実際に採用している Heroku Connectの活用方法です。
なでしこナースは人材紹介サービスなので、求職者である看護師、求人者である病院・施設、サービスを運営する4ULの3つのプレイヤーが存在します。 図にするとこのような形になります。 プレイヤーごとにシステムが異なる構造で、看護師はHeroku、病院・施設はSalesforce の Partner Community、運営者はSalesforceという三層構造です。 こういうシステム構成にすることで、SalesfoceとHerokuの強みを両方活かし、サービス開発を素早く行えるようにしています。
Heroku と Salesforce のハイブリット構成では当然データベース同期が必要になるので、Heroku Connectを使用しています。
SalesforceのオブジェクトとHeroku Postgresのテーブルを双方向に同期してくれるアドオン あくまでも主となるのはSalesforceオブジェクト。同期対象のオブジェクトとそのカラムをHeroku Connectコンソールで選択すると、オブジェクトに対応したテーブルが自動生成される。逆方向はできない Heroku PostgreSQL -> Salesforceの同期時、Salesforceのヴァリデーションに引っかかると同期エラーが起きる。 テーブル作成はHeroku Connectを介してしか行えない(フレームワークのマイグレーション機能は原則そのまま使えない) Salesforce側のオブジェクト定義に依存するので、テーブル名、カラム名やデータ型、データ長さは変更できない 親と子どちらのレコードが先に同期されるか分からないので、FK(外部参照制約)は使えない(貼ることは可能だが、FKエラーで同期失敗する) サロゲートキーとしてIDカラムが生成されるが、Salesforce側には同期されない
結構色々制約があります。 概ね、より自由度の高いRDBMSであるPostgreSQL が Salesforceのデータの持ち方に合わせている感じです。 ユニークキーはHeroku Connectのダッシュボード上では貼れませんが、テーブルそのものに貼ることはできます。 複合インデックスも複合ユニークキーも貼れます。 ただしユニークキーはSalesforce側に制約として存在しない場合、Salesforce -> Heroku Postgres 同期時に エラーが発生するので注意が必要です。 特にHeroku Connect使い始めは勝手がわからず同期エラーを発生させがちなので、ログはしっかり見るようにしましょう。 Heroku Connect ダッシュボード上にログは表示されていますが、Herokuのログに流すこともできます。 なでしこナースではHeroku ConnectのログはPapertrailに流しており、エラーログが発生したらSlackに通知するようにしています。
Heroku Connectはデータの同期をよしなにやってくれるものの、自由度の高いRDBMS側がSalesforceに合わせる形になっているため、フレームワークが期待するスキーマから大きく異なっています。 RailsのようなモダンなWebフレームワークは、フレームワークの流儀に従うことで高い生産性を実現しているので、このギャップが大きいと開発が非常に大変になってしまいます。 ここに理想と現実の壁が存在しているわけですが、ここではこの壁をどうやって乗り越えたかをお話します。
Heroku Connectのダッシュボード画面では、このように同期対象のカラムを指定し、必要があればインデックスを追加することができます。 カラム名やデータ型、データ長さは変更できません。
これは一例ですが、Heroku Postgres と Salesforceのカラムの対応はこんな感じです。 createddate、systemmodstamp、isdeletedシステムカラムで、常に同期されます。 Nameもシステムカラムですが、同期するかどうかは任意です。同期が推奨されています。 このほか、Heroku Connectのコンソールには表示されないものの、sfid、_hc_err、_hc_lastopというシステムカラムが自動的に追加されます。
Heroku側が参照のみだったり、そもそも親子関係のない単独のテーブルの場合は問題は起こりません。 しかしHerokuとSalesforce両建てのハイブリッドシステムを構築する場合、当然Heroku側での書き込みも行うし、単独で存在するテーブルなんてほとんどありません。 つまり、PKとFKをどうするか?と言う問題が常に発生するわけです。 Salesforce側のPKであるsfidはSalesforceで発番されるので、Heroku側でInsertが発生した場合に発番できません。 Heroku側のPKであるIDはそもそもSalesforce側に同期されないので、親子関係を表現できません。 では、親子関係を維持するためにどうすれば良いか?と言う問題が出てきます。 厳密には図のようにSalesforce側のsfidを利用すれば親子関係を維持できますが、発番が常にSalesforce側となるため、 Heroku側でPKを使用できるまでに同期を二回繰り返す必要があり、現実的ではありません。 また、Webサービスという観点からみれば、Heroku視点では外部サービスとなるSalesforceに依存する構成は、 色々と弊害がありそうです。
このインピーダンスミスマッチの解決策は、外部IDを使用する、というやり方です。
Postgresのシーケンスを突っ込むのが手っ取り早いですが、より推奨されているやり方は Posgres の uuid_generate_v4() や gen_random_uuid() を使うやり方です。
Conversation__c - Message__cのリレーションの例では、Conversation__cの外部ID(ここではmofID)の設定を行います。
Conversation__cで外部IDの設定を行なっていると、Heroku Connect のカラム定義で、Conversations__r__mofID__c というリレーション解決専用の特別なカラムが表示されるようになります。 ここにConversation__cのPKを登録してやると、Salesforce側でも適切に親子関係のリレーションが行われるようになります。
Railsのマイグレーション定義です。 create_tableはHeroku Connectが動いている環境では不要ですが、Salesforceの存在しないローカル、CI、ReviewAppのために定義しています。 IDカラムからPK定義をドロップ mofid__cにPK定義を追加 mofid__cのためにシーケンスオブジェクトを新規に追加 mofiid__cのデフォルト値に、シーケンスの発番処理を設定
Schema.rbはこんな感じになります。 Idカラムは使用しなくなるのですが、Heroku Connectが自動生成するシステムカラムなので残しています。
Sfdc側の結合の解決に使用される conversations__r__mofid__c に、conversation_idをセットする処理をコールバックで追加します。
Heroku側でもSalesforce側でも、external_idカラムをPKとして使用し、このカラムで結合できるようになりました。 それぞれの処理系で発番を行えるため、同期を行わなくても各々の世界でデータの結合を閉じることができます。 これはつまり、Heroku側でメッセージ送信を行なった場合、同期を行わなくてもHerokuの世界ではメッセージ送信を完了させることができることを意味します。 これの何が重要かというと、Heroku側から見て外部サービスであるSalesforceに依存せずにWebアプリケーションを独立・完結させられることを意味します。 こうすることで、背後にあるSalesforceがなくてもHeroku側単独で動作するため、ローカルでの開発及びテスト、CIでのテスト、Review Appでの動作が全て正常に行えるるようになります。
今年夏頃までは conversations__r__mofid__c のような結合解決用システムカラムを使うのが一番良いやり方だったんですが、最近upsertフィールドというものが追加されており、 こちらの利用が現在は推奨されているようです。 Upsertフィールドが設定されていない場合、Heroku Connectコンソールのマッピング編集画面では常にUpsertフィールドを設定するよう促すアラートがで続けます。 Upsertフィールドになる条件を満たすフィールドが存在するようになると、このアラートの内容が切り替わり、候補となるフィールド名を提示するようになります。 ここではmofID__cがupsertフィールドの候補として提示されています。 画面右下の「Upsert Field」のプルダウンメニューもUpsertフィールド候補ができて初めて表示されるようになります。 ここでmofID__cを選択してSaveすれば、あとはSalesforceがリレーションを解決してくれるでしょう。 残念ながら時間がなくてUpsertフィールドはまだ試せていません。 Conversations__r__mofid__cのようなリレーション解決用の特殊カラムは同期が遅いというアラートがUpsert機能が追加されてから出るようになったので、 今後はこちらを使用するのが一般的になりそうです。 そのうち追試してみたいと考えています。
Heroku Connect で生成されるカラム名は変更できないため、真ん中のようなカラム名になります。 短いものであればまだ良いですが、長いカラム名だと切れ目がどこなのか非常にわかりづらいため、コードを書く、読む面でも非常に扱いづらくなります。 created_atやupdated_atなど、変更は一応できるものの規約で名称の決まっているものもあります。
ここでPostgreSQLの機能である、Updatable View(更新可能ビュー)を使います。 これはPostgreSQL独特の機能で、単一テーブルを参照するビューであれば、Updateを実行できるというものです。 このビューを利用してテーブル名やカラム名をRailsの規約に則ったものに変換しています。 理想と現実のギャップ(インピーダンスミスマッチ)を、更新可能ビューで解消しているわけです。
繰り返しになりますが、Railsのマイグレーションファイルはこんな感じです。 テーブルの作成、PKの変更、インデックスの作成を行なっています。
DBビューのRailsのマイグレーションファイルはこんな感じです。 普通にDDLを叩いているだけですね。 Mofid__cをidとしているのが肝で、こうすることでSalesforce側で設定している外部IDを、Rails側でもIDとして使用できるようになっています。
再掲ですが、Railsのモデル定義はこれ。 self.primary_key はいらない気がしてきますが、これがないとなぜかうまく動きません。 先に説明した通りFK(外部参照制約)を物理的に貼ることができないので、フレームワーク側だけでも外部結合を 強制するように、関連の定義を行なっています。 これはRails4なので、belongs_toにrequired: trueを設定することで、関連を強制できます。 Rails5ではデフォルトでこの挙動になるので、required: trueは書かなくても大丈夫です。 この程度の定義で、DBビューであるmessagesビューに対し、CRUD操作を普通に行えます。 つまり、Rails側の開発者にとっては普通のRailsアプリと同様の開発を行えることを意味します。
テーブルの新規追加ではなく、カラムの追加が発生することもあります。 この場合のマイグレーションファイルはこんな感じ。 ここではread__cという既読未読判別用のカラムを新たにメッセージオブジェクトに追加しています。 マイグレーションファイルでは対象カラムが存在するかどうかを条件式にできるので、 すでにread__cカラムがあるかを調べ、なかったら追加しています。
カラム削除の場合のマイグレーションファイルはこんな感じ。 カラム削除の場合、DROP VIEW を先に実行しないとPosrgreSQLがエラーを吐きます。 ビューから参照されているカラムは消せないからです。
このように二つのインピーダンスミスマッチを解消することで、HerokuとSalesforceが密に連携しながらも、 それぞれが独立した環境で動き、Ruby on RailsとSalesforceそれぞれの流儀で開発を行うことができています。 Web開発では疎結合が汎用性や柔軟性の上でメリットが有ることが多いですが、この事例でも同様です。
このように、ふたつのインピーダンスミスマッチを効果的に解消することで、WebアプリケーションではSalesforceがバックエンドに存在することをあまり意識することなく、 従来の方法論に則ったWeb開発を行うことができます。
現在の開発フローはこんな感じです。 Githubを中心にCIを組み合わせて自動テストを行い、Heroku Pipelineを利用しているあたりは、モダンなHeroku開発そのままだと思います。 Review Appはビジネスサイド(プロダクトオーナー)に実際に動きを見せるために使っているので、サービスが動くのに必要なダミーデータをseed_fuで登録しています。 Salesforceと連動して動く機能はステージング環境までデプロイしないと確認できませんが、 Heroku側のアプリケーションのみでほぼ完結する機能も多いので、 Review Appでほとんどの動作確認を済ますことができています。 なお、ここでCircleCIの代わりにHerokuCIを使うとよりHeroku Pipelineを使いこなしてる感があっていいのですが、現在は使えません。 このなでしこナースプロジェクトではDB Viewを使っている関係上、データベースの構築には rake db:migrate か rake db:migrate:reset する必要があるのですが、 HerokuCIは rake db:schema:load 決め打ちになっているからです。 このコマンドは schema.rbの情報を元にデータベーススキーマ定義を行うので、DB Viewを作ってくれません。 Schema.rb を使わずに structure.sql に切り替えるのも一つの手ですが、Railsのプレーンな、一般的な構成を崩したくなくて、 CircleCIを使っています。
Review Appを利用するためにはapp.jsonを書く必要がありますが、現在こんな感じです。 Postdeployが重要で、rake db:migrate でデータベーススキーマの構築、db:seed_fu でマスタデータやダミーデータの投入を行なっています。 RAILS_ENVをステージングにしているのは、万が一にも本番環境で動作しないようproductionのseed_fuを作成していないからです。 別にseed_fuである必要はないので、通常のseedなどを使っても良いと思います。
Descargar ahora