XF 2.2 Getting error with Entity relations

grantus

Active member
I followed the XF docs about relations but it doesn't seem to work for me.

I have a table battle_points that contains user_id column.

I have this in my entity:

Code:
$structure->relations = [
            'User' => [
                'entity'     => 'XF:User',
                'type'       => self::TO_ONE,
                'conditions' => 'user_id',
                'primary'    => true
            ],
        ];
        $structure->defaultWith = ['User'];

Because I want to match up user_id from both the battle_points and xf_user tables.

This is my query setup:

Code:
$archives = $this->finder('Test\ILL:BattlePoints')
        ->where('winner', 'yes')
        ->where('user_id', '>', 0)
        ->order('battle_date', 'DESC');

        $forum_username = $archives->User->username;

        $page = $params->page;
        $perPage = 20;

        $archives->limitByPage($page, $perPage);

        $viewParams = [
            'archives' => $archives->fetch(),
            'page' => $page,
            'perPage' => $perPage,
            'total' => $archives->total(),
            'forum_username' => $forum_username
        ];

I was using $archives.username in my template which works fine, but to test I did $archives.forum_username and I get the error message:

Code:
LogicException: Unknown relation username accessed on xf_user in src/XF/Mvc/Entity/Finder.php at line 100

I did a dump on the query and it looks correct. What could be giving this error?
 
Solution
But isn't that the same as what I already have?
Actually, taking another look at your code above...

PHP:
$forum_username = $archives->User->username;

At this point, $archives is a finder object. It's not really clear what you expect this line of code to do. When you call fetch on the finder object, it will give you back a collection of entities (sort of like an array of database results). If you iterate over the collection, you will get each entity object in the collection. Given each entity object, you can traverse the defined relations.

You're passing the collection to your template, so to get the corresponding username you would just do something like:

HTML:
<xf:foreach loop="$archives" value="$archive">...

Jeremy P

XenForo developer
Staff member
If $archives is an instance of your battle-points entity then you would use $archives->User in PHP or $archives.User in templates to access the corresponding user entity. Or $archives.User.username to get the username property of the username entity.
 

grantus

Active member
If $archives is an instance of your battle-points entity then you would use $archives->User in PHP or $archives.User in templates to access the corresponding user entity. Or $archives.User.username to get the username property of the username entity.
But isn't that the same as what I already have?

From what I gather in the docs, it's just a matter of setting up the relations with user_id, then I'd be able to access whichever columns I need in the xf_user table, correct?
 

Jeremy P

XenForo developer
Staff member
But isn't that the same as what I already have?
Actually, taking another look at your code above...

PHP:
$forum_username = $archives->User->username;

At this point, $archives is a finder object. It's not really clear what you expect this line of code to do. When you call fetch on the finder object, it will give you back a collection of entities (sort of like an array of database results). If you iterate over the collection, you will get each entity object in the collection. Given each entity object, you can traverse the defined relations.

You're passing the collection to your template, so to get the corresponding username you would just do something like:

HTML:
<xf:foreach loop="$archives" value="$archive">
    {$archive.User.username}
</xf:foreach>
 
Solution

grantus

Active member
Actually, taking another look at your code above...

PHP:
$forum_username = $archives->User->username;

At this point, $archives is a finder object. It's not really clear what you expect this line of code to do. When you call fetch on the finder object, it will give you back a collection of entities (sort of like an array of database results). If you iterate over the collection, you will get each entity object in the collection. Given each entity object, you can traverse the defined relations.

You're passing the collection to your template, so to get the corresponding username you would just do something like:

HTML:
<xf:foreach loop="$archives" value="$archive">
    {$archive.User.username}
</xf:foreach>
Code:
<xf:foreach loop="$archives" value="$archive">
    {$archive.User.username}
</xf:foreach>

This is exactly what I have in my template yet I'm still getting the same error, which is confusing since the xfdump seems to be fine.
 

grantus

Active member
Wait - I spoke too soon!

It was throwing that error because of the $forum_username = $archives->User->username; line. I removed that and the one in the viewparams and now it's good.
 
Top