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

Talinon's avatar

@mostafalaravel

I find it hard to believe that this is a bug in the Laravel core. Even if it were, I highly doubt it would result in a string replacement of "test". This screams developer influence from somewhere.

You have mentioned it happens on all models. You never answered whether or not the models extend Illuminate\Database\Eloquent\Model or something else?

Do you have bootable traits that could be affecting the attributes?

Do you have any registered model events or observers that could be firing? Such as on the retrieved event?

Jaytee's avatar

@talinon I too, was a bit suspicious about it being a core bug. I was hesitant in opening the issue, but I thought for the sake of extra help from the contributors who regularly update the framework, it might help us narrow down the problem and alleviate the probability of it being a bug in the core.

It is an interesting topic tho. It seems the attributes are only modified when a response is returned. I'm thinking it could be a client-side error, as this application is an SPA.

What I do know for sure is that we can rule the database out. The data is consistent. It's happening somewhere between the response layer, so yeah, like you said, a parent model other than Eloquent\Model or a trait could be causing this. But I want to look at the client-side first.

Talinon's avatar

@mostafalaravel

Are you 100% certain that nothing within the vendor directory has been edited? Maybe it's time to wipe out vendor/* and do a composer install.

This might explain why it's different between local and production.

GodziLaravel's avatar

@jaytee

1- the migration : for example if user name is foo http: bar this will return foo bar

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use App\User;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->string('verified')->default(User::UNVERIFIED_USER);
            $table->string('verified_token')->nullable();
            $table->string('admin')->default(User::REGULAR_USER);
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

2- Laravel version : Laravel Framework 5.8.35

3-server specifications :

PHP Version => 7.2.24-0ubuntu0.18.04.1

PDO

PDO support => enabled
PDO drivers => mysql, pgsql

pdo_mysql

PDO Driver for MySQL => enabled
Client API version => mysqlnd 5.0.12-dev - 20150407 - $Id: 3591daad22de08524295e1bd073aceeff11e6579 $

Directive => Local Value => Master Value
pdo_mysql.default_socket => /var/run/mysqld/mysqld.sock => /var/run/mysqld/mysqld.sock

pdo_pgsql

PDO Driver for PostgreSQL => enabled
PostgreSQL(libpq) Version => 10.10 (Ubuntu 10.10-0ubuntu0.18.04.1)
Module version => 7.2.24-0ubuntu0.18.04.1
Revision =>  $Id: 9c5f356c77143981d2e905e276e439501fe0f419 $

pgsql

PostgreSQL Support => enabled
PostgreSQL(libpq) Version => 10.10 (Ubuntu 10.10-0ubuntu0.18.04.1)
PostgreSQL(libpq)  => PostgreSQL 10.10 (Ubuntu 10.10-0ubuntu0.18.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0, 64-bit
Multibyte character support => enabled
SSL support => enabled
Active Persistent Links => 0
Active Links => 0

Directive => Local Value => Master Value
pgsql.allow_persistent => On => On
pgsql.auto_reset_persistent => Off => Off
pgsql.ignore_notice => Off => Off
pgsql.log_notice => Off => Off
pgsql.max_links => Unlimited => Unlimited
pgsql.max_persistent => Unlimited => Unlimited

4- it's in test not production

5- JS code:

<template><span>

    <div aria-hidden="true"
         aria-labelledby="addTrainingModalLabel"
         class="modal fade"
         id="addTrainingModal"
         ref="addNewTrainingModal"
         role="dialog"
         tabindex="-1">
            <div role="document" v-bind:class="{'modal-lg':modalLarge, 'modal-dialog':true}">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="addTrainingModalLabel">{{modalTitle}}</h5>
                        <button aria-label="Close" class="close" data-dismiss="modal" ref="closeAddModal" type="button">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body" v-if="actionButton==='showAddTraining'">
                        <add-training
                                ref="addNewTrainingData"
                                :login-user-id="currentUserId"
                                :authrz-external-training-edit="authrzExternalTrainingEdit"
                        ></add-training>
                    </div>
                    <div class="modal-footer">
                        <button class="btn btn-secondary btn-square" data-dismiss="modal" type="button">Close</button>
                        <button @click="createTraining()" class="btn btn-success btn-square" type="button"
                                v-if="actionButton==='showAddTraining'"
                        ><i class="fa fa-plus"></i> Add
                        </button>
                        <button class="btn btn-primary btn-square" data-dismiss="modal" type="button"
                                v-if="actionButton==='action2'">action2
                        </button>
                    </div>
                </div>
            </div>
        </div>


        <div aria-hidden="true"
             aria-labelledby="deleteTrainingModalLabel"
             class="modal fade"
             id="deleteTrainingModal"
             ref="deleteTrainingModal"
             role="dialog"
             tabindex="-1">
            <div role="document" v-bind:class="{'modal-lg':modalLarge, 'modal-dialog':true}">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="deleteTrainingModalLabel">{{modalTitle |sentenceCutter(3)}}</h5>
                        <button aria-label="Close" class="close" data-dismiss="modal" ref="closedeleteModal"
                                type="button">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        Are you sure to delete?
                    </div>
                    <div class="modal-footer">
                        <button class="btn btn-secondary btn-square" data-dismiss="modal" type="button">Close</button>

                        <button @click="deleteTraining()" class="btn btn-danger btn-square" data-dismiss="modal"
                                type="button"
                                v-if="actionButton==='showDeleteTraining'"><i class="fa fa-remove"></i> Delete
                        </button>
                    </div>
                </div>
            </div>
        </div>


        <div aria-hidden="true"
             aria-labelledby="editTrainingModalLabel"
             class="modal fade"
             id="editTrainingModal"
             role="dialog"
             tabindex="-1">
            <div role="document" v-bind:class="{'modal-lg':modalLarge, 'modal-dialog':true}">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="editTrainingModalLabel">{{modalTitle}}</h5>
                        <button aria-label="Close" class="close" data-dismiss="modal" ref="closeEditModal"
                                type="button">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body" v-if="actionButton==='showEditTraining'">
                        <edit-training :key="componentKey"
                                       :authrz-external-training-edit="authrzExternalTrainingEdit"
                                       :training-id-param="trainingDetailId"
                                       :login-user-id="currentUserId"
                                       ref="editTrainingData"></edit-training>
                    </div>
                    <div class="modal-footer">
                        <button class="btn btn-secondary btn-square" data-dismiss="modal" type="button">Close</button>
                        <button @click="editTraining()" class="btn btn-primary btn-square" type="button"
                                v-if="actionButton==='showEditTraining'"
                        ><i class="fa fa-floppy-o"></i> Save
                        </button>
                        <button class="btn btn-danger btn-square" data-dismiss="modal" type="button"
                                v-if="actionButton==='showDeleteTraining'"><i class="fa fa-remove"></i> Delete
                        </button>
                    </div>
                </div>
            </div>
        </div>









       <ul class="nav nav-tabs" id="myTab" role="tablist">
            <li class="nav-item">
                                <a aria-controls="Company"
                                   aria-selected="true"
                                   class="nav-link active"
                                   data-toggle="tab"
                                   href="#tab1"
                                   id="tab1-tab"
                                   ref="tab1"
                                   role="tab">As participant
                                </a>
            </li>

            <li class="nav-item">
                <a
                        aria-controls="other"
                        aria-selected="false"
                        class="nav-link"
                        data-toggle="tab"
                        href="#tab2"
                        id="tab2-tab"
                        role="tab">As trainer</a>
            </li>
        </ul>


        <div class="tab-content" id="myTabContent">

            <div aria-labelledby="tab1-tab" class="tab-pane fade show active" id="tab1" role="tabpanel">


                <v-server-table :columns="columnsParticipants" :options="options" ref="trainingsTableTab1"
                                url="/api/trainings?meAsParticipant">
                <span slot="actions" slot-scope="{row}">

                    <button
                            @click="showTrainingEdit(row.id)"
                            class="btn btn-primary btn-square btn-sm"
                            data-target="#editTrainingModal"
                            data-toggle="modal" v-if="authrzTrainingsEdit"
                    >
                        <i aria-hidden="true" class="fa fa-pencil"></i>
                        Edit</button>

                    <button
                            @click="showDeleteTraining(row)"
                            class="btn btn-danger btn-square btn-sm"
                            data-target="#deleteTrainingModal"
                            data-toggle="modal"
                            v-if="authrzTrainingsEdit"
                    ><i aria-hidden="true"
                        class="fa fa-times"></i> Delete</button>

                </span>


                    <span slot="external_urls" slot-scope="{row}">

                      <p v-for="link in row.external_urls">
                        {{ link.name }} {{link.url}}
                      </p>

                    </span>


            </v-server-table>




            </div>
            <div aria-labelledby="tab2-tab" class="tab-pane fade" id="tab2" role="tabpanel">
                <v-server-table :columns="columnsTrainers" :options="options" ref="trainingsTableTab2"
                                url="/api/trainings?meAsTrainer">
                <span slot="actions" slot-scope="{row}">

                    <span slot="trainers" slot-scope="{row}">

                <ul id="trainerstmp">
                  <li v-for="trainer  in row.trainers">
                    {{ trainer.name }}
                  </li>
                </ul>

            </span>


                    <span v-if="row.intern || authrzExternalTrainingEdit" >
                        <button
                            @click="showTrainingEdit(row.id)"
                            class="btn btn-primary btn-square btn-sm"
                            data-target="#editTrainingModal"
                            data-toggle="modal" v-if="authrzTrainingsEdit"
                    >
                        <i aria-hidden="true" class="fa fa-pencil"></i>
                        Edit</button>

                    <button
                            @click="showDeleteTraining(row)"
                            class="btn btn-danger btn-square btn-sm"
                            data-target="#deleteTrainingModal"
                            data-toggle="modal"
                            v-if="authrzTrainingsEdit"
                    ><i aria-hidden="true"
                        class="fa fa-times"></i> Delete</button>

                    </span>


                </span>


                <span slot="participants" slot-scope="{row}">

                <ul id="participantsTab1">
                  <li v-for="participant  in row.participants">
                    {{ participant.name }}
                  </li>
                </ul>

            </span>

                <span slot="trainers" slot-scope="{row}">

                <ul id="participantsTab2">
                  <li v-for="trainer  in row.trainers">
                    {{ trainer.name }}
                  </li>
                </ul>

            </span>

                    <span slot="external_urls" slot-scope="{row}">

                      <p v-for="link in row.external_urls">
                        {{ link.name }} {{link.url}}
                      </p>

                    </span>


            </v-server-table>



                <button class="btn btn-square btn-success pull-left"
                        data-target="#addTrainingModal"
                        data-toggle="modal" type="button" v-if="authrzTrainingsEdit"
                        v-on:click="showAddTraining()"><i aria-hidden="true" class="fa fa-plus"></i> Add training
            </button>

                <p class="pb-3"></p>

            </div>

        </div>

</span></template>

<script>
    import addTraining from "./addTraining";
    import editTraining from "./editTraining";

    export default {
        props: ['authrzTrainingsEdit','loginUserId','authrzExternalTrainingEdit'],
        name: "trainings",
        components: {
            'add-training': addTraining,
            'edit-training': editTraining,
        },

        data() {
            return {

                componentKey: 0,
                actionButton: '',
                modalTitle: "modal title",
                modalContent: "modal content",
                modalLarge: false,
                deletedTrainingId: null,

                teamLeaderOfWithDescendants: null,
                currentUserId: null,
                columnsParticipants: ['id', 'title','begin_date', 'levelName', 'certified','certification_expired_date','certification_number','external_urls'],
                columnsTrainers: ['id', 'title', 'begin_date', 'levelName', 'certified','external_urls', 'actions'],
                dateColumns: ['begin_date', 'end_date'],
                options: {
                    //https://github.com/matfish2/vue-tables-2/blob/master/lib/config/defaults.js
                    texts: {
                        filter: "",
                        filterPlaceholder: "Search",
                        limit: "",
                    },

                    initialPage: 1,
                    sortable: ['id'],
                    filterable: ['id'],
                    perPage: 5,
                    perPageValues: [5, 10, 20, 50, 100],
                    requestAdapter(data) {
                        return {
                            query: data.query,
                            limit: data.limit,
                            page: data.page,
                            sort: data.orderBy ? data.orderBy : 'id',
                            direction: data.ascending ? 'asc' : 'desc'
                        }
                    },
                    responseAdapter({data}) {
                        return {
                            data: data.data,
                            count: data.total,
                            teamLeaderOfWithDescendants: data.teamLeaderOfWithDescendants
                        }
                    },

                    templates: {
                        certified(h, row) {
                            return (row.certified === true) ? '✔' : '';
                        },
                        begin_date(h, row) {
                            return moment(row.begin_date).format('DD/MM/YYYY') + " to " + moment(row.end_date).format('DD/MM/YYYY');
                        },
                        certification_expired_date(h, row) {
                            if(!moment(row.certification_expired_date).isValid())return '';
                            let certificationExpiredDate =  moment(row.certification_expired_date).format('DD/MM/YYYY') ;
                            return certificationExpiredDate;
                        },


                    },


                    headings: {
                        id: 'Id',
                        description: 'Description',
                        begin_date: 'Date',
                        title: 'Title',
                        levelName: 'Level',
                        certified: 'Certified',
                        participants: 'Participants',
                        trainers: 'Trainers',
                        actions: 'Actions',
                        certification_expired_date:'Exp date',
                        certification_number:'Cert number',
                        external_urls:'Links',
                    }
                }

            }
        },
        mounted() {

            $("input:text:visible:first").focus();
            this.getFullTeamDescendants();
        },
        methods: {
            showTrainingEdit(trainingId) {
                this.componentKey++;
                this.trainingDetailId = trainingId;
                this.modalLarge = true;
                this.modalTitle = "Edit training";
                this.actionButton = "showEditTraining";
            },

            deleteTraining() {
                axios.delete('/api/trainings/' + this.deletedTrainingId)
                    .then(response => {
                        if (response.data === 'ok') {
                            this.$refs.trainingsTableTab2.refresh();
                            this.$refs.trainingsTableTab1.refresh();
                            this.trainingDeleteConfirmation()
                        }
                    });
            },
            showDeleteTraining(row) {
                this.deletedTrainingId = row.id;
                this.modalLarge = false;
                this.modalTitle = "Training: " + row.title;
                this.actionButton = "showDeleteTraining";

            },

            showAddTraining() {

                this.$root.$emit('clearForm');
                this.modalLarge = true;
                this.modalTitle = "Add new training";
                this.actionButton = "showAddTraining";

            },
            createTraining() {

                let newTraining = this.$refs.addNewTrainingData.newTraining;
                //(newTraining.defaultTrainer !== null)?newTraining.trainers.push(newTraining.defaultTrainer):''

                console.log(newTraining);

                axios.post('/api/trainings',
                    newTraining
                )
                    .then((response) => {
                        this.$refs.closeAddModal.click();
                        this.trainingCreatedConfirmation();
                        this.$refs.trainingsTableTab2.refresh();
                        this.$refs.trainingsTableTab1.refresh();
                    })
                    .catch(error => {
                        if (error.response.status === 422) {
                            this.$refs.addNewTrainingData.errors = error.response.data.errors;
                        }
                    });
            },

            trainingByUser(event) {
                this.options.requestAdapter = (data) => {
                    return {

                        userId: event.target.value,
                        query: data.query,
                        limit: data.limit,
                        page: data.page,
                        sort: data.orderBy ? data.orderBy : 'id',
                        direction: data.ascending ? 'asc' : 'desc'
                    }
                };
                this.$refs.trainingsTableTabe2.refresh();

            },
            getFullTeamDescendants() {
                axios.get(`api/trainings?fullTeamDescendants`)
                    .then(response => {
                        this.teamLeaderOfWithDescendants = response.data.data.sort((a, b) => (a.user_full_name > b.user_full_name) ? 1 : -1);
                        this.currentUserId = response.data.user_id;
                        console.log(this.teamLeaderOfWithDescendants);
                    });
            },

            editTraining() {
                let updatedTraining = this.$refs.editTrainingData.updateTraining;
                axios.post('/api/trainings/' + updatedTraining.id,
                    updatedTraining
                )
                    .then((response) => {
                        this.$refs.trainingsTableTab2.refresh();
                        this.$refs.trainingsTableTab1.refresh();
                        this.$refs.closeEditModal.click();
                        this.trainingUpdatedConfirmation();
                        //this.showTrainingEdit(0);

                    })
                    .catch(error => {
                        if (error.response.status === 422) {
                            this.$refs.editTrainingData.errors = error.response.data.errors;
                        }

                    });
            }
        }
        ,
        notifications: {
            trainingUpdatedConfirmation: {
                title: 'Training',
                message:
                    'Training updated with success',
                type:
                    'success',
                timeout:
                    2000
            }
            ,
            trainingCreatedConfirmation: {
                title: 'Training',
                message:
                    'Training added with success',
                type:
                    'success',
                timeout:
                    2000
            }
            ,
            trainingDeleteConfirmation: {
                title: 'Training',
                message:
                    'Training deleted with success',
                type:
                    'success',
                timeout:
                    2000
            }
            ,
        }
    }
</script>

<style scoped>

</style>

Thanks

Jaytee's avatar

Could you provide the migration for the trainings table please, not the user table.

What package are you using for the Datatable?

Give what @talinon suggested, a go. Remove the vendor folder and install with composer again.

Jaytee's avatar

I've closed that issue I opened on Github, since this works fine locally, but not on the testing server

GodziLaravel's avatar

Here the 'trainings' migration ,

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTrainingsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('trainings', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title')->nullable()->unique();
            $table->dateTime('begin_date')->nullable();
            $table->dateTime('end_date')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('trainings');
    }
}

About database :

postgreSQL 10.10

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432


I will remove the vendor folder

question :

should I remove vendor from local then git push , and from server git pull or

in local : remove the folder and composer

in server : remove the folder and composer

Talinon's avatar

@mostafalaravel You shouldn't need to use git at all. vendor/ shouldn't be under version control. Just delete it and run composer install. Composer will restore your vendor directory according to your composer.lock file.

1 like
Jaytee's avatar

Want to test something else out?

In the trainings controller, where you're returning the training, do:

file_put_contents(base_path('test.json'), $training->toJson());

Should create a file in the root directory of the application, and paste the contents of the model attributes into it. Copy that contents here.

Jaytee's avatar

Okay, I've noticed something. Your original thread up top show's a different response to reply number 9 in this thread, yet they're both a training model.

Reply number 9 has more attributes.

Why is this? Are you doing any merging with other tables into one result set? If so, it could be overriding the values on merge.

Talinon's avatar

@jaytee He put ellipses in the original post. I think he was just truncating the results for brevity?

Jaytee's avatar

@talinon Don't think so because look at the migration schema for the trainings table.

Relationships wouldn't merge into a flattened array. The result would be a multidimensional array. So some sort of merging is happened which could be the cause.

If you look at the JavaScript code, a few different models have a title attribute. It's entirely possible this is happening.

Talinon's avatar

@jaytee I see your point. This just strengthens my suspicion that something is going on in a model event or something.

"training ftp: test aftehttps:r adding the permission:"

This result also is strange. Why did the "https" get inserted there? Seems like a garbage memory reference or something.

Jaytee's avatar

@talinon

I've just looked at the vue tables source code. A lot of merging occurs almost everywhere, including on columns once it's been fetched. Also a little bit of regex, but I can't understand that well.

If you look at the JS code above, you can see a <v-server-table> which is handling trainers, participants and external_urls. Correct me if i'm wrong, but they all share a common attribute which is title.

So there could be two culprits here:

  1. Your idea of the model, or memory error. I get that the model could be causing this, but how would memory cause this, when it's only happening when returning the data as a response?

  2. Having different test data on the test server, and local, would cause the errors only to happen on test, and not local. Probably because the local database isn't populated as similar to the testing database. Tie that with the merging, and wa-la.

Datatables are always doing things behind the scenes that we don't know about. We had a lot of issues when using complex queries, or columns, with Laravel Datatables.

Jaytee's avatar

Imagine if this thread was all a lie LMAO. Whats that rule?

"Never trust user input". That also applies to this forum haha

GodziLaravel's avatar

@jaytee @talinon

I removed the vendor folder and composer install , the problem stills the same !

But with file_put_contents(base_path('test.json'), $training->toJson());

the "http:" exists !!!!! you can see it in title attribute bellow

Is this a good sign ?

{"id":7,"title":"training l http:after adding the permission","begin_date":"2019-11-05 00:00:00","end_date":"2019-11-05 00:00:00","created_at":"2019-11-05 15:19:35","updated_at":"2019-11-08 18:44:00","level_id":1,"certified":true,"external_urls":[{"url":null,"name":""}],"certification_number":"AZD557AZD7","certification_expired_date":"2019-07-13","intern":true,"certification_body_name":"name","external_trainer_name":null,"external_trainer_company_name":null,"levelName":"level kiwi","trainers":[{"name":"mostafa abdellaoui","last_name":"mostafa","first_name":"abdellaoui","pivot":{"training_id":7,"user_id":503}},{"name":"bruno sas23","last_name":"bruno","first_name":"sas23","pivot":{"training_id":7,"user_id":508}}],"categories":[{"id":2,"competence":"competence name 2","created_at":"2019-10-22 14:54:51","updated_at":"2019-10-22 14:54:51","wheel_id":1,"pivot":{"training_id":7,"category_id":2}},{"id":3,"competence":"competance 3","created_at":"2019-10-23 12:28:51","updated_at":"2019-10-23 12:28:55","wheel_id":1,"pivot":{"training_id":7,"category_id":3}}],"participants":[{"name":"bruno sas23","last_name":"bruno","first_name":"sas23","pivot":{"training_id":7,"user_id":508}}],"level":{"id":1,"name":"level kiwi","competence_level":0,"description":"basic level","created_at":"2019-10-22 12:40:27","updated_at":"2019-10-22 12:40:23"}}

Talinon's avatar

@mostafalaravel

I've asked a few times what your models extend and whether it includes traits.

Paste your entire Training model here.

Here is another test to rule out model events.

Within your controller, add this:

public function show($id)

    \Event::fake();  // <-- add this line

    {
        $training = Training::with([
            'trainers', 'categories', 'participants'
        ])->findOrFail($id);


        return $training;
    }

Then see what it spits out.

GodziLaravel's avatar

@talinon

the model content:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class training extends Model

{

    protected $casts = [
        'external_urls' => 'object'
    ];
    protected $appends = ["levelName"];

    public function getLevelNameAttribute()
    {
        if ($this->level == null) return null;
        return level::find($this->level_id)->name;
    }

    public function categories()
    {
        return $this->belongsToMany(category::class);
    }

    public function level()
    {
        return $this->belongsTo('App\level');
    }

    public function participants()
    {
        return $this->belongsToMany(User::class, 'participants_training')
            ->select([DB::raw("CONCAT(last_name,' ', first_name) AS name"),
            'last_name', 'first_name'
            ]);
    }

    public function trainers()
    {
        return $this->belongsToMany(User::class, 'trainers_training')
            ->select([
                DB::raw("CONCAT(last_name,' ', first_name) AS name"),
                'last_name', 'first_name'
            ]);

    }
}

I added \Event::fake(); nothing happened same result !

Talinon's avatar

@mostafalaravel

I still don't understand where external_urls is coming from. You must have global scopes registered or something..

Try this:

public function show($id)
    {
        $training = Training::withoutGlobalScopes()->with([
            'trainers', 'categories', 'participants'
        ])->findOrFail($id);


        return $training;
    }
GodziLaravel's avatar

@talinon

external_urls is a field in training table that I added after in another migration :

    public function up()
    {
        Schema::table('trainings', function (Blueprint $table) {
            $table->jsonb('external_urls')->nullable();
            $table->string('certification_number',50)->nullable();
            $table->date('certification_expired_date')->nullable();
            $table->boolean('intern')->default(true);
        });
    }

the problem is not only with this model , it'a in all models even with users model !

I tested $training = Training::withoutGlobalScopes()->with([ and nothing changed !

Talinon's avatar

I'm running out of ideas... and I can't explain why there is a difference between local and production.

I don't think it's driver related because it works in Tinker.

You could try intercepting all queries to see if there is a clue there...

public function show($id)

\DB::connection()->enableQueryLog();

    {
        $training = Training::with([
            'trainers', 'categories', 'participants'
        ])->findOrFail($id);

dd(\DB::getQueryLog());

    }


GodziLaravel's avatar

@talinon

here the result

array:4 [▼
  0 => array:3 [▼
    "query" => "select * from "trainings" where "trainings"."id" = ? limit 1"
    "bindings" => array:1 [▼
      0 => "7"
    ]
    "time" => 0.76
  ]
  1 => array:3 [▼
    "query" => "select CONCAT(last_name,' ', first_name) AS name, "last_name", "first_name", "trainers_training"."training_id" as "pivot_training_id", "trainers_training"."user_id" as "pivot_user_id" from "users" inner join "trainers_training" on "users"."id" = "trainers_training"."user_id" where "trainers_training"."training_id" in (7) and "users"."deleted_at" is null ◀"
    "bindings" => []
    "time" => 0.99
  ]
  2 => array:3 [▼
    "query" => "select "categories".*, "category_training"."training_id" as "pivot_training_id", "category_training"."category_id" as "pivot_category_id" from "categories" inner join "category_training" on "categories"."id" = "category_training"."category_id" where "category_training"."training_id" in (7) ◀"
    "bindings" => []
    "time" => 0.77
  ]
  3 => array:3 [▼
    "query" => "select CONCAT(last_name,' ', first_name) AS name, "last_name", "first_name", "participants_training"."training_id" as "pivot_training_id", "participants_training"."user_id" as "pivot_user_id" from "users" inner join "participants_training" on "users"."id" = "participants_training"."user_id" where "participants_training"."training_id" in (7) and "users"."deleted_at" is null ◀"
    "bindings" => []
    "time" => 0.73
  ]
]
Talinon's avatar

Alright, hold up a minute. I've reviewed the very start of this thread and something isn't adding up.

You originally said, here are your results:

Tinker:

 title: "training https: test after adding the permission: https",

Controller:

"title": "training  test after adding the permission: https",

phpPgAdmin:

training https: test after adding the permission: https

So Tinker and phpPgAdmin are correct.

I then asked you to dd($training); from your controller, in which you replied:

Here the result : it exists!

"title" => "training https: test after adding the permission: https"

Which is correct. So what is the problem here?

Am I correct in saying that this is only happening when the model is cast?

So what happens if you try this in Tinker?

App\training::find(7)->toArray();

GodziLaravel's avatar

@talinon

Yes and here the summary of the situation :

Tinker : exists

>>> App\training::find(7);
=> App\training {#3140
     id: 7,
     title: "training l http:after adding the permission",
     begin_date: "2019-11-05 00:00:00",
     end_date: "2019-11-05 00:00:00",
     created_at: "2019-11-05 15:19:35",
     updated_at: "2019-11-08 18:44:00",
     level_id: 1,
     certified: true,
     external_urls: "[{"url": null, "name": ""}]",
     certification_number: "AZD557AZD7",
     certification_expired_date: "2019-07-13",
     intern: true,
     certification_body_name: "name",
     external_trainer_name: null,
     external_trainer_company_name: null,
   }

with the controller : Not exists

$training = App\training::with([
            'trainers', 'categories', 'participants'
    ])->findOrFail(7);
return $training;

returns :

{
  "id": 7,
  "title": "training l after adding the permission",
  "begin_date": "2019-11-05 00:00:00",
  "end_date": "2019-11-05 00:00:00",
  "created_at": "2019-11-05 15:19:35",
  "updated_at": "2019-11-08 18:44:00",
  "level_id": 1,
  "certified": true,
  "external_urls": [
    {
      "url": null,
      "name": ""
    }
  ],

with dd($training);: exists

  #attributes: array:15 [▶]
  #original: array:15 [▼
    "id" => 7
    "title" => "training l http:after adding the permission"
    "begin_date" => "2019-11-05 00:00:00"
    "end_date" => "2019-11-05 00:00:00"
    "created_at" => "2019-11-05 15:19:35"
    "updated_at" => "2019-11-08 18:44:00"
    "level_id" => 1
    "certified" => true
    "external_urls" => "[{"url": null, "name": ""}]"
    "certification_number" => "AZD557AZD7"
    "certification_expired_date" => "2019-07-13"
    "intern" => true
    "certification_body_name" => "name"
    "external_trainer_name" => null
    "external_trainer_company_name" => null
  ]
  #changes: []
  #dates: []

Now with Tinker : App\training::find(7)->toArray(); exists

>>> App\training::find(7)->toArray();
=> [
     "id" => 7,
     "title" => "training l http:after adding the permission",
     "begin_date" => "2019-11-05 00:00:00",
     "end_date" => "2019-11-05 00:00:00",
     "created_at" => "2019-11-05 15:19:35",
     "updated_at" => "2019-11-08 18:44:00",
     "level_id" => 1,
     "certified" => true,
     "external_urls" => [
       {#3146
         +"url": null,
         +"name": "",
       },

Talinon's avatar

@mostafalaravel

Looking thru the framework code, it looks like mutators get cached. Try clearing your cache.

php artisan cache:clear

Would also explain the difference between local/production

GodziLaravel's avatar

@talinon

 php artisan cache:clear
Application cache cleared!

I did it but nothing changed unfortunately . is there some other clears I can do ?

Talinon's avatar

And you're certain that your production code is up-to-date with your local code?

Go into your app/ directory on your production server and do a string search thru all your code for "test" and "http" and see if there is anything that could be causing it.

grep -rn "http"

grep -rn "test"

If that doesn't shed any light, then my professional analysis is that your server is borked.

GodziLaravel's avatar

@talinon

nothing special :(

About the up-to-date , yes of course and at least 2 times per day I git pull from GItLab because I still developing this project !

 grep -rn "http"
Http/Controllers/Teamleader/TestApiController.php:18:        $response = $client->request('POST', 'https://app.teamleader.eu/login/', [
Http/Controllers/Teamleader/TestApiController.php:48:        $client = new Client(['base_uri' => 'https://api.teamleader.eu/']);
Http/Controllers/Teamleader/TestApiController.php:96:        $client = new Client(['base_uri' => 'https://api.teamleader.eu/']);
Http/Controllers/TeamleaderAuthController.php:16:        $query = http_build_query(
Http/Controllers/TeamleaderAuthController.php:24:        return redirect('https://app.teamleader.eu/oauth2/authorize?'.$query);
Http/Controllers/TeamleaderAuthController.php:31:            $http = new Client();
Http/Controllers/TeamleaderAuthController.php:32:            $response = $http->post('https://app.teamleader.eu/oauth2/access_token',[
Http/Traits/TeamLeaderAPI.php:17:        $response = $client->request('POST', 'https://app.teamleader.eu/login/', [
Http/Traits/TeamLeaderAPI.php:49:        $client = new Client(['base_uri' => 'https://api.teamleader.eu/']);
Mail/MailtrapExample.php:36:                'link' => 'https://mailtrap.io/inboxes'

 grep -rn "test"
Http/Controllers/Teamleader/TestApiController.php:78:    public function testMe()
Http/Controllers/UserController.php:31:        //$latestActivities = Activity::with('user')->latest()->limit(100)->get();
Http/Controllers/UserController.php:39:            'latestLog'
User.php:107:    public function latestLog()
User.php:109:        return $this->hasOne(Log::class, 'causer_id')->latest();

Please or to participate in this conversation.