Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

stevgouws's avatar

Not even sure what to name what I want to do...

Say I have many clubs that all need to pay a yearly subscription, so will have several subscription records.

I've set up my relationship: In Club.php

    public function subscriptionRecords() {
        return $this->hasMany('App\ClubSubscriptionRecord');
    }

But now I want to set up something where I can easily check if each club has paid their subscription in the current year or not, and would like easy access to it like just do $club->getSubscriptionPaid and get a boolean back.

which I've tried to do as an Accessor in Club.php like this:

    public function getSubscriptionPaid() {
        $lastPaymentDateYear = $this->subscriptionRecords()->orderBy('payment_date')->pluck('payment_date')->last()->year;
        $currentYear = Carbon::now()->year;
        if ($lastPaymentDateYear = $currentYear) {
            return true;
        } else {
            return false;
        }
    }

This get's me the error:

LogicException with message 'Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation

...so I guess I'm not supposed to do it as an Accessor, but I don't what it's called what I want to do so very difficult to search for how/where to do it.

Any help would be appreciated.

0 likes
3 replies
bobbybouwmann's avatar

If you want an accessor you need to follow a certain convention. That convention is getXAttriubte(). So in your case your method needs to be called getSubscriptionPaidAttribute().

You can now access this property like so

$club->getSubscriptionPaidAttribute(); // returns boolean
1 like
Salomoni's avatar
Salomoni
Best Answer
Level 8

The error is not about the getSubscriptionPaid method or you are trying to eager load it somewhere else in your app.

Please check laravel.log file for more details and files where the error occurs.

To get the method work as an accessor rename it as getSubscriptionPaidAttribute and you can call it like $club->subscriptionPaid

And finally you can just return $lastPaymentDateYear = $currentYear from the accessor method without wrapping it in a if statement.

1 like
stevgouws's avatar

Thanks guys, so looks like it works even without using the convention of 'Attribute' at the end of the name, as long as I call it like $club->getSubscriptionPaid() instead of $club->getSubscriptionPaid, I was missing the () at the end.

However if I use the correct convention (which I will) then I can also call it as $club->subscriptionPaid or $club->subscription_paid.

@Salomoni I don't think it had to do with eager loading because I just created the method and was trying it out in tinker. And thanks for the tip about the if statement, much cleaner!

1 like

Please or to participate in this conversation.