0

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();
        }
    }

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.