0

I know the question has already been posted, and answers where given ; I read this topic ; Of course I can try to insert the sObject and get the error listing the missing fields,

But isn't it a 'better' way to do it ?

I'm pretty sure I had found a way, but can't find it anymore ;

At this moment my favorite option remains to use the Schema Builder in wich it's obvious (red lines in front of each required attribute) -->

enter image description here

But isn't it a way to show a column required / not required, in the object manager ? -->

enter image description here

Same question, in the dev console ? -->

enter image description here

Thanks for your help !

  • Looks like a candidate for idea exchange. – Pranay Jaiswal Sep 7 '18 at 13:30
  • How do you do ? How do people do, most of the time ? Thanks ! – Alexis MASSON Sep 7 '18 at 13:38
  • 2
    I use IDE like eclipse/VS code to retreive metadata of Object. The metadata XML contains a required tag which tells me if its a required field of not. Other way is looking at UI/Describe call like you mentioned. – Pranay Jaiswal Sep 7 '18 at 13:40
5

Please note that fields can be made required via other means which are difficult or impossible to detect. Validation rules, triggers, and Process Builder can all introduce errors when a field is not populated (sometimes more intentionally than others).

Given the above, you can still iterate the describe to find which fields are practically required if you like. Here is a script showing how to do so.

for (SObjectField field : SObjectType.MyObject__c.fields.getMap().values())
{
    if (!field.getDescribe().isNillable())
    {
        system.debug(field);
    }
}
| improve this answer | |
  • Thanks for this pointing this issue, and thanks for the code ! Ok, I'll assume my idea wasn't as good as it first seem to me, thanks for your usefull help ! – Alexis MASSON Sep 7 '18 at 14:39
2

For API version <= 44.0, there is no explicit isRequired method but there are a few methods that you can leverage to find required fields:

for (Schema.SObjectField fieldToken : Schema.SObjectType.MyObject__c.fields.getMap().values())
{
    Schema.DescribeFieldResult fieldDescribe = fieldToken.getDescribe();
    if (
        // These methods are on DescribeFieldResult
        !fieldDescribe.isNillable()
        && fieldDescribe.isCustom()
        && !fieldDescribe.isDefaultedOnCreate() // optional
    )
    {
        system.debug(field);
    }
}

Schema.DescribeFieldResult Documentation

!isNillable() won't exactly get you your required fields since this will also catch auto-numbers and system fields (like Deleted).

isCustom() I believe is an auto-inclusion since this type of use case typically relates to custom objects and using auto-numbering for a Name is pretty common in my experience. Exclude this is you are leveraging the standard required fields for record creation.

!isDefaultedOnCreate() may be good to add depending on whether or not you care about values being explicitly declared that would otherwise default.

| improve this answer | |
0

Found this, Could help also !

Not responding at my whole question, but helps.

enter image description here

| improve this answer | |
0

Even though I'm not providing any answers to the original question, I want to add more information to this post that could be useful for others.

Apparently, the nillable field in the SObject Describe API is not related to the required/optional property of an SObject fields.

Take for instance the description of the ServiceAppointment object, which specifies the ParentRecordId as nillable. However, the following code fails:

ServiceAppointment sa = new ServiceAppointment();
insert sa;

The error code I receive when trying to execute the code above is:

System.DmlException: Insert failed. First exception on row 0; first error: 
REQUIRED_FIELD_MISSING, Required fields are missing: [ParentRecordId]: [ParentRecordId]

So if we take that error message as truthful, we can succeed:

Account a = new Account(Name='Some Name');  // `Name` is required for `Account`.
insert a;
ServiceAppointment sa = new ServiceAppointment(ParentRecordId=a.Id);
insert sa;

In fact, none of the fields marked as non-nillable are actually required when creating a ServiceAppointment object. Such fields are the following:

[
  "Id",
  "OwnerId",
  "IsDeleted",
  "AppointmentNumber",
  "CreatedDate",
  "CreatedById",
  "LastModifiedDate",
  "LastModifiedById",
  "SystemModstamp",
  "Address",
  "EarliestStartTime",
  "DueDate",
  "IsAnonymousBooking"
]

The reason behind that I think is that all of them are provided with default values when creating a record even though they are not flagged as defaultValue, defaultValueFormula nor defaultedOnCreate (which makes it even more confusing 😠).

I did find out however that the following formula closely approximates the required fields shown in the GUI

function isFieldMandatory(field) {
  return (
    field.createable &&
    !field.defaultedOnCreate &&
    !field.nillable
  );
}

Such formula will say that the following fields are mandatory, which "matches" what is shown in the GUI (with the exception of the only actual required field, whcih is ParentRecordId):

[
  "EarliestStartTime",
  "DueDate"
]

New Service Appointment GUI form

So a message to you, future hackers: I wish you better luck that what I had so far 😞

| improve this answer | |
New contributor
Jay Vercellone is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.