phplaravellaravel-5relationship

Overwritten create method doesn't fire for relationship()->create()


I want to add a new tag to a model by the following call:

Modul::find($id)->tags()->create($request->all());

The create method in the tag Modul is:

public static function create(array $attributes = [])
{
    $attributes['user_id'] = Auth::user()->id;
    return parent::create($attributes);
}

But it says that the user_id is not set.

When I call

Modul::find($id)->tags()->create(array_merge($request->all(), ['user_id' => Auth::user()->id]));

everything works fine.

I made an echo call inside the create function but it's never called. So is there a secound create function I have to overwrite?


Solution

  • The create method you're calling is not defined on the Tag model, it's defined on the relation class. So if you're relation is many-to-many, then the create method is the one defined on the Illuminate\Database\Eloquent\Relations\BelongsToMany class.

    That method calls the newInstance model method internally. So if you want to add the user_id to the attributes, you can override that method or even the __constructor, as those methods create a new instance of the model. So this should work in your case:

    public function newInstance($attributes = [], $exists = false)
    {
        $attributes['user_id'] = Auth::id();
    
        return parent::newInstance($attributes, $exists);
    }
    

    That being said, it's better to pass the user_id as as a parameter, because otherwise you're tightly coupling the model to the authentication system, and it might have unforeseen results as the method is also used internally by Eloquent.