1

I am building a trigger on an object called project board. so whenever a record is updated/inserted I want it to fire. It is linked to another object called project. So what I want is to count all the records inserted in a project board for one project. And based on the count of that, check or uncheck a checkbox field in Project object. Can someone clarify on the code as why is it wrong.( I know that :( )

trigger project_board_added on Project_Board__c (after insert, after update) 
{

    List<Id> pfid = new List<Id>();
    for(Project_Board__c a : Trigger.new) 
        {
            if(String.isBlank(a.Project__c) == false && String.isEmpty(a.Project__c) == false) 
            {
                pfid.add(a.Project__c);

            }
        }

    Integer pbcount = [Select count() From Project_Board__c Where Project_Firm__c != null AND Project__c=: pfid];

    Map<Id, Project__c> proj = new Map<Id, Project__c>([Select Id,Project_Board_Added__c FROM Project__c Where id IN :pfid]);

    if(pbcount  == 0 )
    {    
    for ( Project_Board__c u:Trigger.new)
        {
            Project__c a = proj.get( u.Project__c);
            if(a!= null)
            {
                a.Project_Board_Added__c = false;
            }    
        }
    }
    else if(pbcount > 0 )
    {    
    for ( Project_Board__c u:Trigger.new)
        {
            Project__c a = proj.get( u.Project__c);
            if(a!= null)
            {
                a.Project_Board_Added__c = true;
            }    
        }
    }
}

This is the alter code which I am trying to run but to no solution. This says error: Variable Project__c doesnt exist. ...

List pfid = new List(); if(String.isBlank(Project_Board__c.Project__c) == false && String.isEmpty(Project_Board__c.Project__c) == false) { pfid.add(Project_Board__c.Project__c); } Integer pbcount = [Select count() From Project_Board__c Where Project_Firm__c != null AND Project__c=: pfid];

Map proj = new Map([Select Id,Project_Board_Added__c FROM Project__c Where id IN :pfid]); if(pbcount == 0 ) { if(Project_Firm__c != null) {proj.get(Project__c).Project_Board_Added__c = false; } } else if(pbcount > 0 ) { if(Project_Firm__c != null { proj.get(Project__c).Project_Board_Added__c = true; } } }

  • I think the pbcount is the overall Project Board count. Your code will always set the Project_Board_Added__c field to true. If you want individual count use Aggregate query grouped by Project and get the count of Project board OR query Project with Project Board. Get the count from anyone of these two options and based on the count for each Project, update the Project's Project_Board_Added__c field to either false or true. – Vignex Nov 25 '14 at 8:14
  • Using triggers you also need to consider the delete case and as you've discovered these triggers can be tricky. If the relationship already is master-detail (or you can change it to master-detail) you can add a count roll-up summary field and let the platform do the work. Your boolean flag can then just be a simple formula that checks if the count is not zero. – Keith C Nov 25 '14 at 8:55
  • @Vignex- what you said makes sense..I am trying to bulkify my code and hence this edit..is it possible that for once I stop considering update/insert through data loader and write the trigger for individual records coming through ? Also the records inserted will be just for one project at a time, so I need that project's id to change Project_board_added field. thoughts? – Himanshu Saxena Nov 25 '14 at 9:30
  • @Keith- Deletion in my objects is done through updating null values to fields inside object, so I suppose update will take care of that scenario. What I am more interested in is to make sure the if{} statements to work correctly ? any suggestions ? – Himanshu Saxena Nov 25 '14 at 9:32
  • 1
    That is an unusual approach to deletion... Again, the roll-up field is what I would use. But in your trigger, the fundamental problem is the one that @Vignex identified: you need to be doing an aggregated query grouped by the Project. – Keith C Nov 25 '14 at 9:55
2

This aggregate query will produce a map where the key is the ID of the project and the value is the number of matching project board objects:

Map<Id, Integer> m = new Map<Id, Integer>();
for (AggregateResult ar : [
        select Project__c p, count(Id) c
        from Project_Board__c
        where Project_Firm__c != null
        and Project__c in:pfid
        group by Project__c
        ]) {
    m.put((Id) ar.get('p'), (Integer) ar.get('c'));
}

Incorporate this into your solution.

PS

The overall trigger would look something like this:

trigger project_board_added on Project_Board__c (after insert, after update) {

    Set<Id> pIds = new Set<Id>();
    for (Project_Board__c pb : Trigger.new) {
        if (pb.Project__c != null) pIds.add(pb.Project__c);
    }

    if (pIds.size() > 0) {

        Map<Id, Integer> m = new Map<Id, Integer>();
        for (AggregateResult ar : [
                select Project__c p, count(Id) c
                from Project_Board__c
                where Project_Firm__c != null
                and Project__c in :pIds
                group by Project__c
                ]) {
            m.put((Id) ar.get('p'), (Integer) ar.get('c'));
        }

        Project__c[] updates = new Project__c[] {};
        for (Id pId : pIds) {
            Integer c = m.get(pId);
            if (c == null) c = 0;
            updates.add(new Project__c(Id = pId, Project_Board_Added__c = c > 0));
        }
        update updates;
    }
}
  • @HimanshuSaxena The above solution from Keith will remove the need of pbcount in your code. You just need to loop your Project Board records and pass the Project Id to this map and get the count. if the count is >0, make it to TRUE else make the field to false. – Vignex Nov 25 '14 at 10:04

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.