wellUKnow
wellUKnow

Reputation: 29

Laravel eloquent model encoding json error

I am getting a encoding error with eloquent and i don't understand how to fix it

this is the the error:

Illuminate\Database\Eloquent\JsonEncodingException: Error encoding model [App\Models\UserIp] with ID [] to JSON: Recursion detected in file

this is the the function :

/**
     * @param string $ip     the user ipaddress
     * @param string $status failed or succeeded ?
     * @param string $type   the type of action performed
     *
     * @throws \JsonException
     */
    function logUserIp(string $ip, string $status, string $type)
    {

        $user = UserIp::where('ip', '=', $ip)->where('user_id', '=', auth()->user()->id)->first();
        $position = Location::get($ip);
        if (null == $user && false !== $position) {
            $ip = new UserIp();
            $ip->user_id = auth()->user()->id;
            $ip->ip = $ip;
            $ip->country = $position->countryName;
            $ip->country_code = $position->countryCode;
            $ip->status = $status;
            $ip->type = $type;
            $ip->device = json_encode([
                'platform' => Agent::platform(),
                'browser' => Agent::browser(),
                'user_agent' => \request()->server('HTTP_USER_AGENT')
            ], JSON_THROW_ON_ERROR);
            $ip->save();
        }
    }

Upvotes: 0

Views: 1941

Answers (2)

matiaslauriti
matiaslauriti

Reputation: 8092

I saw you fixed your problem, but let me give you some small tips about your code, see my code and compare it with yours:

/**
 * @param string $ip     the user ipaddress
 * @param string $status failed or succeeded ?
 * @param string $type   the type of action performed
 *
 * @throws \JsonException
 */
public function logUserIp(string $ip, string $status, string $type): void
{
    $user = auth()->user();

    if ($position = Location::get($ip) &&
        !$user->userIp()->where('ip', $ip)->exists()
    ) {
        $userIp = new UserIp();
        
        $userIp->ip = $ip;
        $userIp->country = $position->countryName;
        $userIp->country_code = $position->countryCode;
        $userIp->status = $status;
        $userIp->type = $type;
        $userIp->device = [
            'platform' => Agent::platform(),
            'browser' => Agent::browser(),
            'user_agent' => request()->server('HTTP_USER_AGENT')
        ];

        $user->associate($userIp);

        $user->save();
    }
}

See how I changed the code. Also, for $userIp->device to save without the need of json_encode, you will have to add this to your UserIp model:

/**
 * The attributes that should be cast.
 *
 * @var array
 */
protected $casts = [
    'device' => 'array',
];

So you can later consume $userIp->device as an array, no need to do json_decode($userIp->device).

Also, related to $user->associate, read this.

Upvotes: 0

Peppermintology
Peppermintology

Reputation: 10210

There error is occuring from this line:

$ip->ip = $ip;

You have a parameter named $ip in your function signature (string $ip) but you're then overriding that value later with $ip = new UserIp(), so $ip is no longer a string but is now an instance of UserIp.

Later in your code you then assign the new $ip of type UserIp to your $ip->ip property. You're basically assigning the $ip instance of UserIp to the ip property on itself. I assume you actually mean to be the original string $ip.

Change the name of your new UserIp() variable and you should be good.

Upvotes: 3

Related Questions