[users-module]: Override UserModel.php with an extension (error: call to undefined method).
Created 5 years ago by finnito

Hi all!

I have been wanting to override the UserModel.php in the users-module so that I can provide some extra reverse relationship methods. I have been reading around and found that you need to bind the extension in reverse, so I have done this in my Addon Service Provider:

protected $bindings = [
    UserModel::class => \Finnito\MembersModule\User\MembersUserModel::class,
    UserPresenter::class => \Finnito\MembersModule\User\MembersUserPresenter::class,
];

My MembersUserModel.php looks like this:

<?php namespace Finnito\MembersModule\User;

use Anomaly\UsersModule\User\UserModel;
use Finnito\MembersModule\ActiveMember\ActiveMemberModel;

class MembersUserModel extends UserModel
{
    public function getSignups()
    {
        return $this->hasMany(ActiveMemberModel::class, "user_id")->get();
    }
}

And my MembersUserPresenter.php looks like this:

<?php namespace Finnito\MembersModule\User;

use Anomaly\UsersModule\User\UserPresenter;

class MembersUserPresenter extends UserPresenter
{
    public function signups()
    {
        return $this->object->getSignups();
    }
}

Now, for some reason it seems to work fine with my MembersUserPresenter because I can alter my presenter to return "Hi!" and it all goes smoothly, but if I run it as above, I get the error:

An exception has been thrown during the rendering of a template ("Call to undefined method Illuminate\Database\Query\Builder::getSignups()").

This error seems to indicate to me that the model is not being bound, perhaps due to the boot order of things? I honestly can't for the life of me find anything that I can do to fix this, and some help would be appreciated!

Thanks,

Finn

ryanthompson  —  5 years ago Best Answer
finnito  —  5 years ago

@ryanthompson Ah looks cool, so if I want to bind signups to the UserModel it might look something like this:

public function register(UserModel $model)
    {
        $model->bind(
            'signups',
            function () {
                /* @var EloquentModel $this */
                return $this
                    ->hasMany(ActiveMemberModel::class, 'user_id')
                    ->get();
            }
        );
}

I’m not familiar with the morph functions but it looks like they pertain to polymorphic relationships; so I’d be okay just using hasMany or one of the regular relationship methods?

Thanks for the guidance!

ryanthompson  —  5 years ago

I personally would use get_ prefix for the return method. The signups would return the relationship (so drop the ->get() part) and then have another method like get_signups more a-tune to what I have done in comments.

This way you can return the relation and manipulate it as needed if necessary. Does that make sense? Basically emulating the same relation() and getRelation() pattern that's found everywhere.

finnito  —  5 years ago

Yep that makes sense! It works a treat so thanks