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

Hondaman900's avatar

How to force data into the created_by_id field.

I'm using a webhook to process a Stripe transaction. In the webhook I set up the new user account, or upgrade it, as the case may be. I have a table for settings and I pre-populate that with default settings, but one of the fields is created_by_id, which I cannot set. Because the webhook is a side process, there is no Auth::User() or authenticated logged-in user. When I try to save data to the fields, my code creates the new settings record, but leaves the created_by_id field blank. I need that field to associate those settings to their user.

My code in my webhook is:

$newSettings = new Setting;
                    
                    $newSettings->federalLTCGrate = 15;
                    $newSettings->stateLTCGrate = 9;
                    $newSettings->federalITrate = 20;
                    $newSettings->stateITR = 9.3;
              		...
                    $newSettings->created_by_id = $user->id;
                    Log::info("New Settings: ".$newSettings);
                    $newSettings->save();

All fields are saved correctly. I can send the data collection to the log , as you can see, and I clearly see the correct user ID for that field in the data array, it just doesn't get saved but everything else is.

I know that is being done in my settings model:

But how can I override this and force that field to update with the ID number I send it?

0 likes
19 replies
Snapey's avatar

You set the id in the webhook so provided you are getting $user->id then you should be good.

Unless... you have an observer that tries to set the same field.

Hondaman900's avatar

@Snapey yes, I agree, I should be good as I get a correct $user->id and pass it to created_by_id and then save. I'm starting to think the Settings model is blocking this, or overwriting it with what it has for Auth::User()->id which would be null in a webhook.

Hondaman900's avatar

@martinbean Sorry, it's defined upstream in the webhook. I use the Stripe customer ID to fetch the user associated with the incoming webhook payload.

$user = User::where('stripe_customer_id', $charge['customer'])->first();

That works fine. I do have a good $user object, including $user->id , and I pass that to the created_by_id field before I save. All other fields save except for this one, the created_by_id field. I'm starting to think the model is overriding it.

martinbean's avatar

@Hondaman900 As someone else mentioned, do you have an observer that would normally set this field automatically when the model is saved? My guess is you have an observer doing something like…

public function created(Setting $setting)
{
    $setting->created_by_id = Auth::id();
}

But because there is no user in your webhook handler, Auth::id() is going to return null and override the value you had tried setting in the webhook handler.

paskwaal's avatar

The log will show the data/attributes filled on the model at that moment. With Laravel’s magic, you can even push temporary attributes to your model, and they’ll appear in your log as well. Additionally, a save action will NOT fail if the required column(s) are missing in your database at the time of saving.

To confirm, have you created a migration to add the created_by_id column in your database (preferably with a foreign key relation)? Do you have another part of your application where you can create and save a Setting with a created_by_id? This way, you can rule out the possibility that the issue originates from the webhook.

Hondaman900's avatar

@paskwaal Yes, I have that field and watch it directly with MySQL Workbench to see if i's being populated. How will the log show me the filled data/attributes? Do you mean that I write code to output to the log for debugging, or are you saying that there's an existing log of all database transactions, or...? Can you elaborate please?

paskwaal's avatar

@Hondaman900 In your initial post you mentioned 'I can send the data collection to the log , as you can see, and I clearly see the correct user ID for that field in the data array'. Only thing I wanted to point out is that you can't validate the working of properties on your model with a log that way. Because you could inject any property you want and still be able to see it in the log. So for example;

$user = new \App\Models\User();
$user->demo = 'hoi';
Log::info('New user: ' . $user);

This will so me a log with; New user: {"demo":"hoi"}

But in my user table in the database there isn't a demo column. A save action then will just ignore the property, because it couldn't map it to a column in the database. From there I would say the bug is somewhere in a mismatch of the column and the attribute.

Side note; With the code you are showing, you wouldn't even need to assign the properties as fillable in the first place, because you aren't using the mass assignment.

Hondaman900's avatar

@paskwaal Yes, understood. My issue is I have the data assigned, I have the field, I'm just not getting the data saved in the field. All the other fields get saved to the record, just not this one.

Hondaman900's avatar

Commenting out the created_by function in the Settings model makes no difference, so that theory is not holding up. I was optimistic that was the issue.

public function created_by()
    {
        //return $this->belongsTo(User::class, 'created_by_id');
    }
Hondaman900's avatar

So I moved this code to a helper that I can call and pass a known value for $user->id. This is the helper code. Note that I put in two debug outputs to the log, checking for the value held in $user->created_by_id before and after the save record. It looks like the value dissappears during the save. What could be causing this???

And here's the output to the log:

[2024-11-07 09:54:41] local.INFO: Existing settings:   
[2024-11-07 09:54:41] local.INFO: Existing settings boolean: 1  
[2024-11-07 09:54:41] local.INFO: New Settings before save: 2275  
[2024-11-07 09:54:41] local.INFO: New Settings after save:   
Hondaman900's avatar

If it helps, here's my original migration when I set up the Settings table. Now I'm thinking I'm seeing the database default values rather than seeing my data being written to the other fields:

    public function up()
    {
        Schema::create('settings', function (Blueprint $table) {
            $table->increments('id');
            $table->decimal('federalLTCGrate',5,2)->default('15.00');
            $table->decimal('stateLTCGrate',5,2)->default('9.30');
            $table->decimal('federalITrate',5,2)->default('20.00');
            $table->decimal('stateITR',5,2)->default('9.30');
            $table->decimal('commissionREsale',5,2)->default('5.00');
            $table->decimal('closing_costsREsale',5,2)->default('1.00');
            $table->integer('federalLTGholding_days')->default('365');
            $table->integer('stateLTGholding_days')->default('30');
            $table->decimal('married_residential_exclusion_limit', 15, 2)->default('500000.00');
            $table->decimal('single_residential_exclusion_limit', 15, 2)->default('250000.00');
            $table->integer('created_by_id')->unsigned()->nullable();
            $table->foreign('created_by_id')->references('id')->on('users')->onDelete('cascade');
            $table->timestamps();
        });
    }
Hondaman900's avatar

Nope, I modified the values in my helper and they are being written to the database, so the save values code is working, just not to the created_by_id field.

paskwaal's avatar

@Hondaman900 by default Laravel creates an User tabel with id as big integer column. When setting up a foreign key, the column type of the foreign key should match the column type of the primary key (id) in the User table. I see you use an integer as column type, is indeed the User's column type of the id column an integer?

I don't really think that is the problemen because you would already have had an error when running that migration. When saving the 'created_by_id' that id should exists in the user table but you would also have had an error when saving then.

rust17's avatar

@Hondaman900 When creating a new Setting, the system checks if a user with the id 2275 exists. If the user doesn't exist, the database foreign-key constraint will prevent the Setting from being created.

Hondaman900's avatar

@rust17 Yes, I thought of that, but I'm pulling the ID from the database and a real existing customer record, so that look-up should return true. However, I think I have resolved the issue.

Hondaman900's avatar

I think I have resolved this. It looks like a filter I use to globally set the created_by_id for all models is the culprit by setting the created_by_id to null if it doesn't pass an auth check. I put in a condition to check for the first field in the Setting model and step over that statement if found. That isolates my Settings from this function (which I still need for other models).

trait FilterByUser
{
    protected static function bootFilterByUser()
    {
        if(! app()->runningInConsole()) {
            
            static::creating(function ($model) {
                Log::info("Model in Filter Pre: ".$model);
                if(!$model->federalLTCGrate) {
                    $model->created_by_id = Auth::check() ? Auth::getUser()->id : null;
                }
                Log::info("Model in Filter Post: ".$model);
            });
(...)

By checking for the first field in that model I can bypass this for my specific settings model. It now works.

Thank you all for the help narrowing this down and resolving my issue.

Please or to participate in this conversation.