0

I am working with Laravel Eloquent models and have gotten stuck on an inheritence issue.

I have got BaseModel class, which has protected static $dynamicRelations = []; parameter, and some methods to work with that.

And then I have multiple other classes, extending BaseModel, for this example let's say PageModel and EventModel.

If I create a dynamic relation on the page model, as such PageModel::setDynamicRelation, it puts it in the static variable:

    public static function setDynamicRelation($key, $callback)
    {
        static::$dynamicRelations[$key] = $callback;
    }

This way, I can add a dynamic relationship to the model. So if I do PageModel::setDynamicRelation('banners', ...), then on an instance of PageModel I can call PageModel->banners to retrieve the relationship values.

The issue is, that the relations are kept in the BaseModel static parameter, and are inherited by other models. So if I set the relationsip on PageModel, and then instantiate an EventModel, it also gets those same relationships, which is not correct.

How can I make it so that the relationships are stored in the child class and are not inherited by other classes? I.e. need to store a copy of $dynamicRelations on the class that the methods are called upon, so all the children don't share same relations?

Thanks!

5
  • if you want something that dynamic why not use morph? Commented Nov 28, 2016 at 17:22
  • @jycr753 could you expand on this please? I have a structure where I need to allow modules changing other modules, so a module called PageBanners can add a dynamic relationship to the Page model, without actually changing the code in Page model. Commented Nov 28, 2016 at 17:25
  • That shouldn't be happening. In your example, EventModel shouldn't be getting the relationships of the PageModel, they are two different instances. Commented Nov 28, 2016 at 17:26
  • Yes, that is my exact problem. They both extend same BaseModel, which has the static parameter, and they seem to share it for some reason? Commented Nov 28, 2016 at 17:27
  • To be clear, I add a relationship using a static method, so like PageModel::setDynamicRelationship, however instances of both PageModel and EventModel inherit the same relationships from the BaseModel::$dynamicRelationships Commented Nov 28, 2016 at 17:28

1 Answer 1

1

Do you have tests showing this?

So you are stating that you do not want Late Static Bindings

Static properties on parent classes that are defined in child classes don't propagate to other child instances that extend the parent model. For example, Illuminate\Database\Eloquent\Model has the protected static $globalScopes = []; property but when you add a global scope to any model extending Model it pushes it in this array just as you are doing with your $dynamicRelationships array but those instances do not get reflected in the classes extending Model.

See Laravel's implementation of this here

Sign up to request clarification or add additional context in comments.

1 Comment

I thought there would be a more elegant solution than keeping static::class as the array keys, but if the framework is doing that way then it must be good enough. Thanks a lot for this!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.