Object Model support


Generate Models

require 'sf_cli/sf/model'
require 'sf_cli/sf/model/sf_command_connection'

# first, you must prepare the connection
conn = SfCli::Sf::Model::SfCommandConnection.new target_org: your_org, instance_url: your_org_url

# then set it to Model module
SfCli::Sf::Model.set_connection conn

# generates some model classes (for example, Account and Contact)
SfCli::Sf::Model.generate %w[Account Contact]

Apply to sf command

rows = sf.data.query "SELECT Id, Name FROM Contact WHERE Name = 'Akin Kristen'", model_class: Contact

# the array object contains Contact object instances
rows.size  # 1
rows.first # <Contact: @Id="0035j00001RW3xbAAD", @Name="Akin Kristen">
rows.first.Name # Akin Kristen

Using Independently

Initialize and save a record

c = Contact.new(:Name => "John Smith")
c.Name # "John Smith"
c.save

Find and update a record

c2 = Contact.find(c.id)                  # find by record ID
c2 = Contact.find_by(Name: "John Smith") # find by Name

c2.Name = "Johnny Smith"
c2.save # update

Delete a record

c2 = Contact.find(c.id)
c2.delete

Query and Get a record

contact = Contact.select(:Id, :Name).where(Name: 'Akin Kristen').take
contact # => #<Contact: @Id="0035j00001RW3xbAAD", @Name="Akin Kristen">
contact.Name # Akin Kristen

Contact.select(:Name).where(Name: 'John Smith', LastModifiedDate: :Yesterday).take
Contact.select(:Name).where(Name: 'John Smith').where(LastModifiedDate: :Yesterday).take # same as above

Query and Get records

contacts = Contact.where(LastModifiedDate: :Yesterday).all     # get all contacts who are modified yesterday
accounts = Account.where.not(LastModifiedDate: :Yesterday).all # get all accounts that are *not* modified yesterday

Query and Get CSV data

csv = Contact.select(:Id, :Name).where(LastModifiedDate: :Yesterday).to_csv

Aggregate functions

Account.where(BillingCountry: 'Japan').count      # count accounts whose billing country is Japan
User.where(country: 'USA').max(:LastModifiedDate) # get the latest LastModifiedDate of users in USA
Case.min(:LastCreatedDate)                        # get the date when the oldest case was created

Child-Parent Relationship

contact = Contact.select(:Id, :Name, "Account.Name").where(Name: 'Akin Kristen').take
contact # <Contact: @Id="0035j00001RW3xbAAD", @Name="Akin Kristen", @Account= #<Account @Name="Aethna Home Products">>
contact.Account.Name # Aethna Home Products

Parent-Children Relationship

 = Account.select(:Id, :Name, "(SELECT Name FROM Contacts)").take
 # <Account @Contacts=[#<Contact @Name="Akin Kristen">], @Id="0015j00001dsDuhAAE", @Name="Aethna Home Products">
.Name             # Aethna Home Products
rows.Contacts            # [#<Contact @Name="Akin Kristen">]
rows.Contacts.first.Name # Akin Kristen

Time keywords such as ‘yesterday’ or ‘LAST_N_DAYS:N’ with symbol style

Contact.select(:Name).where(LastModifiedDate: :Yesterday).take       # "SELECT Id, Name FROM Contact WHERE LastModifiedDate = Yesterday"
Contact.select(:Name).where(LastModifiedDate: :"LAST_N_DAYS:5").take # "SELECT Id, Name FROM Contact WHERE LastModifiedDate = LAST_N_DAYS:5"

Array for ‘IN’ keyword

Contact.select(:Name).where(Name: ['Jonny Good', 'John Smith']).all # same as "SELECT Name FROM Contact WHERE Name IN ('Jonny Good', 'John Smith')"

Using partial soql directly

Contact.select("Id, Name").where("LastModifiedDate = LAST_N_DAYS:5").all

Ternary style

Contact.select(:Id, :Name).where(:LastModifiedDate, :>=, :"LAST_N_DAYS:5").all # SELECT Id, Name FROM Contact WHERE LastModifiedDate >= LAST_N_DAYS:5
Account.select(:Id, :Name).where(:Name, :LIKE, "%OIL%").all                    # SELECT Id, Name FROM Account WHERE Name LIKE '%OIL%'

Get schema

schema = Account.describe
schema.name                   # Account
schema.field_names            # [Id, Name, ....]
schema.fields.name_and_labels # returns all field name and label pairs

Sometimes it’s better to use raw SOQL when it gets complecated.

accounts =
  SfCli::Sf::Model.connection.exec_query(
    "SELECT Id, Name FROM Account WHERE Name like '%Hoge' OR (Age <= 30 AND BillingCity IN ['Tokyo', 'NewYork'])",
    model_class: Account
  )

About Document

As of now, most of object model class libary is not mentioned in online document. The reason is:

  1. it is not main feature of sf_cli

  2. the auther thinks that most of things you should know is written in this document.

But you can locally generate the complete document, which contains things related to object models:

$ git clone git@github.com:tmkw/sf_cli.git sf_cli
$ cd sf_cli
$ bundle config set with development
$ bundle install
$ yardoc