Search code examples
laraveleloquentmass-assignment

Laravel mass-assignment insert new record create() alternative?


I have a 'users' table and 'activation_tokens' table. I have a relation in User model as hasOne(ActivationToken::class);

This is all working fine. Now I want to create a token when creating a user. So I call

$user->ActivationToken()->create(array('token'=>'RANDOM_STRING")); 

This is all good, but I am hitting the mass-assignment error. I do not want to set 'token' as fillable.

Instead I try

    $activationToken = new ActivationToken();
    $activationToken->token = 'RANDOM_STRING";
    $activationToken->save();

Which is ok but it does not set the user_id field in query. I guess I could do it manually by setting $activationToken->user_id = $user->id; But this feels wrong since the ORM should be handling this automatically as far as documentation seems to advertise. So I think I am doing something wrong?

I couldn't figure out how to do this correctly. Any hints?

Thanks!


Solution

  • So, after searching the web quite a bit I found out that I can stop mass-assignment restrictions temporarily.

        ActivationToken::unguard();
        $user->ActivationToken()->create(array('token'=>str_random(100)));
        ActivationToken::reguard();
    

    So this seems to work fine. Also jsphpl's response was quite nice and the solution below is working fine too.

        $activationToken = new ActivationToken();
        $activationToken->token = str_random(100);
        $activationToken->user()->associate($user);
        $activationToken->save();
    

    Of course some questions remain.

    1- Why is

    $activationToken->user()->associate($user);
    

    better than

    $activationToken->user_id = $user->id;
    

    2- Once the unguard line executed:

    ActivationToken::unguard();
    

    Are there any way that the table can be abused before reguard() is called by another PHP process? Note: I am guessing it effects the running process only so in my case it should be safe perhaps...

    Anyway, these are outside of the scope of the original question so...

    Thanks for all the responses!