What could cause load_relationship to fail?

Hi all,

I’m running to a weird problem and would appreciate ideas on what’s going on.

I’m running a logic hook that’s supposed to check the bean’s flex related parent (here as $parentBean) for any related accounts and, if such exist, fill its id to another field in the bean. Here’s the simplified code:

 $key = Relationship::retrieve_by_modules('Accounts', $bean->parent_type, $GLOBALS['db']);
 if (!empty($key)) {
    $parentBean->load_relationship($key);
    $accountIDs = $parentBean->$key->get();
    if (!empty($accountIDs)) {
        $bean->account_id = current($accountIDs);
    }
}

This doesn’t however work. I know that:

  • Relationship::retrieve_by_modules returns a value, ie. $key exists,
  • $parentBean holds the bean of the parent record as expected,
  • load_relationship($key) returns false, even though
  • The relationship named $key exists in the database,
  • QR&R or rebuilding relationships doesn’t have an effect, and
  • The tested parent has a relationship with an Account.

This happens at least when the parent is a Project. Apparently the relationship fails to load, and so get() is executed against a nonexistent link, producing a fatal error.

Even with debug-level logging suitecrm.log doesn’t give out much:

 [15640][1][INFO] Query:    SELECT * FROM relationships
                     WHERE deleted=0
                     AND ( 
                     (lhs_module = 'Accounts' AND rhs_module = 'Project') 
                     OR 
                     (lhs_module = 'Project' AND rhs_module = 'Accounts')
                     )

 [15640][1][INFO] Query Execution Time:0.00058698654174805

 [15640][1][DEBUG] SugarBean[Project].load_relationships, Loading relationship (projects_accounts).

 [15640][1][DEBUG] SugarBean.load_relationships, failed Loading relationship (projects_accounts)

If I execute the query above manually, it returns the correct line in the table. Apache’s errorlog isn’t too informative either:

PHP Fatal error: Uncaught Error: Call to a member function get() on null in **.php:174

Line number corresponds to the $accountIDs = $parentBean->$key->get(); line above., and the stack trace holds no surprises.

Test instance is running SuiteCRM 7.11.13. I can’t figure out what’s happening. Does anyone have an idea what’s wrong here?

Are you using a debugger? Have you stepped through the code of load_relationship to see why it’s failing?

Make sure that the $key is exactly in the format expected; for example, load_relationships expects accounts, not account, not Accounts

1 Like

Hi @pgr and thanks for your input! Good to see you still around :slight_smile:

I’m yet to use Xdebug to see if it provides any results; I was hoping I just missed some common issue and solution would be simple. I’ll get back to you after some deeper debugging.

I think $key should be exactly as required since it is retrieved by a Relationship::retrieve_by_modules(), or does that method produce unreliable results? This is the first time I’m hitting such issue. It seems as if the relationship is correctly queried from the database and the relationship is found, but then something goes wrong.

Sometimes there are subtle differences (incongruencies, even) between the way module names are expressed in different areas of the code.

I wouldn’t assume the retrieve_by_modules outputs names in the format that load_relationships expects to receive them.

You can test this by trying the load_relationships with these slight variations ( accounts , account , Accounts) and see if it works.

Still working on Xdebug, there’s such a nice weather (gasp)here that I did some gardening in between.

Relationship::retrieve_by_modules() goes pretty much undocumented (even the comments in the source are copy-pasted from Relationship::retrieve_by_sides() and wrong) and AFAIK is inherited from Sugar as it is, but isn’t determining relationship names for loading them the whole purpose of that method?

Although I do suspect that the problem has something to do with the way the traditional Sugar modules mix singular and plural forms in names.

Ok, now I’m getting there. @pgr you were right; you can’t trust retrieve_by_modules().

First of all, Xdebug confirmed that Relationship::retrieve_by_modules() returned projects_accounts, which is exactly the same as the relationship_name in relationships table of the database. That is also the name in metadata files. One might think that then projects_accounts should be the name by which to load the relationship…

… But no. By using that name, load_relationship() method returns null and so rest of the code fails fatally. So I went through the SugarBean::load_relationship() method breaking on each line, and Houston, we have (found) a problem:

public function load_relationship($rel_name)
{
    ...
    $fieldDefs = $this->getFieldDefinitions();
    //find all definitions of type link.
    if (!empty($fieldDefs[$rel_name])) {
    ...
}
    $GLOBALS['log']->debug("SugarBean.load_relationships, failed Loading relationship (" . $rel_name . ")");
return false;

The function is looking for projects_accounts from the field definitions of Project. And sigh there is none. Instead, it is named accounts:

$fieldDefs["accounts"] = array(
    "name" => "accounts",
    "type" => "link",
    "relationship" => "projects_accounts",
    "source" => "non-db",
    "ignore_role" => true,
    "vname" => "LBL_ACCOUNTS",
);

So there lies the problem. I guess I need to manually check the names for each possible Flex relate module and then hard-code the names used in field definitions there. Quite a frustrating “feature”.

Hopefully v8 will ditch all these inconsistencies inherited from Sugar. :wink:

1 Like