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

laracoft's avatar

Overriding firstOrNew() of a model

Is there a way to override firstOrNew() of a model?

I would like to associate a few models during the New() phase.

Thank you.

0 likes
24 replies
tykus's avatar

I would be very reluctant to override any of these core Eloquent methods; if you want something custom, then write your own function.

laracoft's avatar

@tykus

The good english terms have been used up, so I just wanna reuse them. What I'm trying to do is for example I have the Sales model, I will have Sales_online and Sales_offline models and they extend the Sales with additional custom behavior

automica's avatar

probably better to call your Models SalesOnline & SalesOffline rather than using an underscore to separate.

laracoft's avatar

@automica

Is that the official naming convention? I have been struggling with this and ended up using the style of Sales_online for my models.

laracoft's avatar

@automica

sorry 1 more question about this, if another model references SalesLead model, how should the method be named?

  1. salesLead() and salesLeads()
  2. sales_lead() and sales_leads()

1 or 2? Thanks.

laracoft's avatar

Yes, I glanced through them as there was a lot to go through. Anyway thanks.

automica's avatar

always camel case for method and relationship names. so 1)

1 like
automica's avatar

Yep. The docs say the table will be snake case plural of the class.

Eg CustomClass will be looking for a table called custom_classes.

It doesn’t say you should use snake case class names.

You can use whatever class name and table names you like if you specify the table name in the model.

bugsysha's avatar

Is there a way to override firstOrNew() of a model?

Yes, just inside of your model (or maybe better trait) define a method with same name.

laracoft's avatar

@bugsysha

This did not work. I did some tracing and it was infinitely recursing.. and I don't understand why.

    public static function firstOrCreate(array $attributes, array $joining = [], $touch = true)
    {
        $result = parent::firstOrCreate($attributes, $joining = [], $touch = true);
        return $result;
    }
bugsysha's avatar

Shouldn't it be:

public function firstOrCreate(array $attributes = [], array $values = [])
{
  $result = parent::firstOrCreate(array $attributes = [], array $values = []);

  // top secret work

  return $result;
}
martinbean's avatar

@laracoft Don’t override core Eloquent methods in your models. Create a service class instead if you need to do additional logic around creating models.

tykus's avatar

Just don't do it @bugsysha - it is not a benign method - there is a lot going on under the surface.

laracoft's avatar

Alright guys, I accept that we should not override firstOrXXX() given the infinite recursion and other weird errors.

Let me test out some code and see if I have other questions. My aim was to have SalesOnline and SalesOffline behave like models but pointing to the sales table. But I think service class probably can't achieve the same effect.

Perhaps Promotion, PromotionGoogle and PromotionAmazon better explains my use case. The idea is I can easily encapsulate the new promotion logic in another class when it comes along.

Thank you for the help so far.

Please or to participate in this conversation.