Home > Mobile >  laravel eloquent foreach loop error Trying to get property 'location_id' of non-object
laravel eloquent foreach loop error Trying to get property 'location_id' of non-object

Time:01-01

This one has happened to me before but I have no idea why and how to avoid it. So I have a static function in a Model which gets all the database rows and uses a foreach loop to read another table but I am unable to correctly read the row data:

    public static function test()
    {
        $accounts = self::where( 'is_enabled', 1 )->get();
        foreach ( $accounts as $account ) {
            $map      = AccountMap::where( 'account_id', $account->id )->first();
            $location = Location::getLocation( $map->location_id );
            $data     = $location->getData();
        }
    }

So the above function gathers an array of items ($accounts) this is then passed into a foreach loop all is fine to this point but if i now use $account->id it is null. The id is shown in the Account object in its attributes folder.

A very similar function is used elsewhere in this model but it uses a passed id and this one works (however $account->id is null). The issue is not the database or column names:

    public static function getThisLocation( $id )
    {
        $account = self::find( $id );
        $map     = AccountMap::where( 'account_id', $id )->first();
        location = Location::getLocation( $map->location_id );
        $data    = $location->getData();

        return $data;

    }

*** EDIT *** Account, AccountMap and Location are all Eloquent models

namespace App\Models;
use Eloquent;
use App\Notifications\AccountMessages;
use Kyslik\ColumnSortable\Sortable;
use Illuminate\Notifications\Notifiable;

/**
 * @method static find(int $id)
 */
class Account extends Eloquent
{
    use Sortable;
    use Notifiable;

public $sortable = [
        'id',
        'name',
        'lastupdate',
        'url'
    ];

public static function test()
    {
        $accounts = self::where( 'is_enabled', 1 )->get();
        foreach ( $accounts as $account ) {
            $map      = AccountMap::where( 'account_id', $account->id )->first();
            $location = Location::getLocation( $map->location_id );
            $data     = $location->getData();
        }
    }

    public static function getThisLocation( $id )
    {
        $account = self::find( $id );
        $map     = AccountMap::where( 'account_id', $id )->first();
        location = Location::getLocation( $map->location_id );
        $data    = $location->getData();

        return $data;

    }

}
namespace App\Models;

use Eloquent;
use Kyslik\ColumnSortable\Sortable;

/**
 * @method static where(string $string, int $id)
 */
class AccountMap extends Eloquent
{
    use Sortable;

    public $sortable = [
        'id',
        'account_id',
        'location'
    ];

}

*** MORE EDIT *** I have confirmed that using $account->attributes['id'] has worked but I've no idea why what I expected to work didn't ($account->id)

CodePudding user response:

The problem must be something related to communication of your model and migration.

Add this dd() to your current test function:

 public static function test()
    {
        $accounts = self::where( 'is_enabled', 1 )->get();
        foreach ( $accounts as $account ) {
            if ($account->id){
                $map      = AccountMap::where( 'account_id', $account->id )->first();
                $location = Location::getLocation( $map->location_id );
                $data     = $location->getData();
            } else {
             dd($account)
            }
        }
    }

Then Check the result and see is there the id filed on your response? If not, The id field doesn't exist on your self Model and it's Your problem's cause.

Finally, Check your model fields easily with :

 public function testReturnOfSelfModel()
    {
        $data= self::all();
        dd($data);
    }

If you have id on this dd function, Your Model working properly. If not, you dont have id field.

Also, it is more professional to change Capitalize your model's first charachter. It sholud be Self, not self.

CodePudding user response:

I'd suggest to setup two proper data Model (a migration would need to create these tables):

class Account extends Model {

    protected $table = 'accounts';

    public $timestamps = false;

    /**
     * The attributes that are mass assignable.
     * @var array
     */
    protected $fillable = [];

    /**
     * The attributes that should be hidden for arrays.
     * @var array
     */
    protected $hidden = [];

}

Unless defining protected $table it will definitely not know what to do.

It's rather unclear what you're even trying to accomplish with AcountMap, but it may need a relation defined; which eg. with return $this->belongsTo(Account::class); ...while simply adding lat & lng to class Account would be far less complex and perfectly fine, while it's only 1 location.

  • Related