Salesforce(SF)とRuby On Railsを連携させるシステムを作成する時に気をつける点をまとめました。
良かったら参考にしてください。
ちなみにRails開発者側からの視点で書いてあります。
環境
サーバー: Heroku
DB: PostgreSQL
連携用gem: Restforce(REST API)
データ設計
データ設計はSF側から始めよう
SF側には制限や制約が多く存在します。
例えば作成できるオブジェクト数は1番安いプラン(1ユーザ3,000円)だと10オブジェクトまでしか作成できない(11オブジェクト以上使いたかったら値段が3倍上がるっ!)とか。
Railsでいうhas_oneや、belongs_toに個数の制限があったりとか。
とかとかRails開発者には想像も及ばない制限があったりするので、RailsからDB設計をすると痛い目をみます(した)。なのでSF側からデータ設計をして、Rails側は追従していくようにしましょう。
Salesforce価格
http://www.salesforce.com/jp/platform/pricing-editions.jsp
Salesforce側
SFのオブジェクト名とRecordType名は重複しないようにしよう。
SFではRecordTypeといって1つのオブジェクトを複数のオブジェクトのように振る舞わせる機能があります。Railsで該当する機能はSTIになります。
そしてRecordTypeを設定したObjectはSTIにて連携することになるのですが、RecordTypeの名前が他のObject名とかぶっていると当然エラーになるので気をつけましょう。
こんな感じで定義すると死ねます。
Object名: Student__c
Contact, RecordType名 Student
RecordType
https://help.salesforce.com/apex/HTViewHelpDoc?id=customize_recordtype.htm&language=ja
SFのAPIコール数は15,000call/24時間なので気をつけよう。
普通にSFのライセンスを購入した場合、APIコール数の上限は1.5万コール/24時間になります。
なのでRails側はこの1.5万コール以内に収まるようにやりくりして設計しましょう。
SFのカスタム項目名はスネークケースで命名しよう。
基本的にSFの項目名はキャメルケース(FullName__c)で定義するようです。
Rails側で連携する場合、カラム名を大体2通りの方法にて変換することになるかと思います(__cも抜くとする)。
- 小文字にする。 => fullname__c => fullname
- スネークケースにする。 => full_name__c => full_name
Railsの経験からすると2.が自然に見え、是非2.を採用したいです。その場合初めからキャメルケースにて定義し、変換していくより、初めからスネークケースとして定義してあれば__cの有る無しのみで判別できます。なのでスネークケースで定義するよう強く依頼すると良いと思います。
SFのマスタ参照する項目は **_sfid と命名しよう。
Railsでは外部のテーブルを参照するカラムは**_id とつけるのが慣習としてあります。
SF側では特にそのようなことは無いので、もし外部オブジェクトを参照するような項目の場合は**_sfidとつけてもらうことでRails側からイメージしやすく作業が進められるかと思います。
Rails側
Rails側のスキーマ管理はRidgepoleを使おう。
Rails<->SF連携の開発をするときは、Railsだけ、Salesforceだけで開発するよりもたくさん試行錯誤をしていくことになります。
連携におけるカラムの付け外しの機会も増えるので、通常のマイグレーションでは結構大変です。
さらにローカルDBとSFをデータ連携させたりするとデータ量が増え同期時間もかかったりするので、気軽にrake db:resetが実行できなくなったりします。
なのでマイグレーション工数を減らす方法としてRidgepoleを使用するのをおすすめします。
Ridgepoleの使い方は以下にまとめましたので参考にしてください。
http://qiita.com/yoshioota/items/de6edcecf94614c2f84f
RailsとSFのカラムのマッピングは __c の有無で判別できるくらいにしよう。
上にも書きましたが、__c の有無位の規則性ならとてもわかり易くRailsエンジニアも作業がし易いです。
なのでスネークケースで行けるよう頑張りましょう。
Rails側のboolean型カラムにはdefault値を必ずつけよう。
DB的にはbooleanは何も設定しないとnull, false, trueの3値扱いになるのですが、SFへnull値を同期させるとエラーが起きます。
なのでnullで同期させないためにdefault値を入れておきましょう。
更にnull: falseをつけておくと完璧です。
SF側へのTimeの送信はiso8601にて変換しておこう
どうも現在のバージョンのRestforceではTime型の場合JSONの変換エラーが出るようです。
なので予めiso8601で変換しておきましょう。
# ちなみにiso8601はこんな感じのフォーマットです
Time.zone.now.iso8601 #=> "2015-08-26T20:11:41+09:00"
SFのpicklistの実現はenumerizeを使い、valueは日本語にしよう。
SFではpicklistの値は日本語で持つのが一般的のようです。
英語で持たせてlabelを日本語にするとかはあまり一般的では無いようです。
なのでそういった場合はenumerizeを利用し、値に日本語を設定して実現すると良いでしょう。
enumerize :user_status,
in: %w(確認中 有効 ロック 退会)
つかenumerize,値を日本語でもてたんですね。
multipickは不明
誰かいい方法教えてください。