Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby エンジニアが Salesforce 業界に 異動して感じたこと

4geru sakisaka
February 27, 2025
120

Ruby エンジニアが Salesforce 業界に 異動して感じたこと

2025/02/27 「Ruby/RailsのヤバいTips共有会 〜転職ドラフトのビールもあるよ〜」で登壇した内容です
https://livesense.connpass.com/event/343652/

4geru sakisaka

February 27, 2025
Tweet

Transcript

  1. コミュニティの特徴 > Salesforce コミュニティ 人の特性 • Salesforce を使っているので話しやすい • Salesforce

    ユーザーといっても種類が様々 ◦ ベンダー:Salesforceの開発を請け負う方 ◦ アドミン:管理者 ◦ ユーザー:営業の方で実際に利用されている方 • Salesforce の領域が広いため、様々な背景の人がいる ◦ エンジニア、情シス、マーケ、IS、FS、カスタマーサクセス
  2. コミュニティの特徴 > Ruby コミュニティ 勉強会、教材 • ドキュメントが多い ◦ Ruby, Rails

    の公式ドキュメント、るびま ◦ 様々なエンジニアが Qiita, Zenn で投稿している記事 • LTや登壇などの機会がとても多い ◦ ローカルコミュニティがたくさんある ◦ カンファレンスも各所で行われている ▪ RubyKaigi, Kaigi on Rails, etc…
  3. コミュニティの特徴 > Salesforce コミュニティ 勉強会、教材 • 勉強する教材が充実している ◦ 公式のハンズオン教材(Trailhead)が用意されている •

    資格試験がたくさんある ◦ 資格を集めるドラゴンボールとも言われている • ユーザーコミュニティ主催のSalesforce の勉強会が活発 ◦ Trailhead を進めるもくもく会がある
  4. Ruby / Salesforce コミュニティで似ていること • 参加する人たちの属性が似ている ◦ 同じ技術を利用している && いろんな背景の人がいる

    • コミュニティイベントがが活発! ◦ ユーザーコミュニティがとても活発 • 大きな変更が行われる ◦ Ruby / Rails は年に1度のバージョンアップ ◦ Salesforce は年に3度のバージョンアップ
  5. 全体の流れ 1. 実現可能か技術調査を行う 2. Ruby でデータパッチの模擬コードの作成  → LLM で Apex

    へ変換 3. LLM を利用してテストコード 4. Salesforce でひたすら検証 ♾ 5. Salesforce の本番環境で実行
  6. Ruby の模擬コード > 前処理① class RubySampleBatchJob < BatchJob def perform

    duplicated_contacts = Contact.all leads = Lead.where(email: duplicated_contacts.pluck(:email)) .where("count(email) = 1") .group_by(:email) # ...本処理へ...
  7. Apex のパッチコード > 前処理① public class SampleBatchJob implements Database.Batchable<SObject> {

    public Database.QueryLocator start(Database.BatchableContext BC) { return Database.getQueryLocator([SELECT Id FROM Contact]); } duplicated_contacts = Contact.all
  8. Apex のパッチコード > 前処理① public class SampleBatchJob implements Database.Batchable< SObject>

    { public void execute( Database.BatchableContext BC, List<Contact> duplicatedContacts ) { // Collect all emails from the contacts Set<String> duplicatedContactEmails = new Set<String>(); for (Contact duplicatedContact : duplicatedContacts) { duplicatedContactEmails .add(contact.Email); } leads = Lead .where( email: duplicated_contacts.pluck(:email) )
  9. Apex のパッチコード > 前処理① // ...続き... // Query leads with

    emails matching the duplicatedContact emails Map<String, Lead> leadsMap = new Map<String, Lead>(); for (Lead lead : [SELECT Id, Email FROM Lead WHERE Email IN :contactEmails] ) { if (!leadsMap.containsKey(lead.Email)) { leadsMap.put(lead.Email, lead); } } // ...本処理へ... leads = Lead .where(email: duplicated_contacts.pluk(:email) ) .group_by(:email)
  10. Ruby の模擬コード > 本処理① class RubySampleBatchJob < BatchJob def perform

    # ... duplicated_contacts.each do |duplicated_contact| lead = leads[duplicated_contact.email]
  11. Apex のパッチコード > 本処理① for (Contact duplicatedContact : duplicatedContacts) {

    Lead lead = leadsMap.get(contact.Email); lead = leads[duplicated_contact.email]
  12. Ruby の模擬コード > 本処理② if lead Database.LeadConvert leadConvert = new

    Database.LeadConvert(); Database.LeadConvertResult result = Database.convertLead(leadConvert); if (!result.isSuccess()) puts "Lead conversion failed ..." next end 技術検証 した Apex のコード
  13. Apex のパッチコード > 本処理② if (lead != null) { Database.LeadConvert

    leadConvert = new Database.LeadConvert(); leadConvert.setLeadId(lead.Id); Database.LeadConvertResult result = Database.convertLead(leadConvert); if (!result.isSuccess()) { System.debug('Lead conversion failed ...'); continue; } 技術検証 した Apex のコード
  14. Apex のパッチコード > 本処理③ Contact originalContact = [SELECT Id FROM

    Contact WHERE Id = :result.getContactId()]; mergeContacts(originalContact, duplicatedContact); っぽい関数が実際の関数になった!
  15. 全体の流れ 1. 実現可能か技術調査を行う 2. Ruby でデータパッチの模擬コードの作成  → LLM で Apex

    へ変換 3. LLM を利用してテストコード 4. Salesforce でひたすら検証 ♾ 5. Salesforce の本番環境で実行