Mathius17
Mathius17

Reputation: 2502

Laravel contains method not working properly

I have a Many to Many relation between User and Role. For some strange reason when I do User::find(1)->roles->contains(2) it just won't work, always throws false (I've checked in the db and indeed user with id 1 has role with id 2).

I'm using it just as the Laravel docs: http://laravel.com/docs/5.0/eloquent#collections

I dug the contains() method and found it in Illuminate\Database\Eloquent\Collecion.php, here it is:

/**
 * Determine if a key exists in the collection.
 *
 * @param  mixed  $key
 * @param  mixed  $value
 * @return bool
 */
public function contains($key, $value = null)
{
    if (func_num_args() == 1 && ! $key instanceof Closure)
    {
        $key = $key instanceof Model ? $key->getKey() : $key;

        return $this->filter(function($m) use ($key)
        {
            return $m->getKey() === $key;

        })->count() > 0;
    }
    elseif (func_num_args() == 2)
    {
        return $this->where($key, $value)->count() > 0;
    }

    return parent::contains($key);
}

Right in the middle of the method, if I change return $m->getKey() === $key; for == it suddenly works. Is this a typo? Should I report it in the repository or make a pull request?

P.S. It will never enter the parent::contains(), or at least in my case.

Upvotes: 0

Views: 1352

Answers (1)

Maksym
Maksym

Reputation: 3428

It may be because you have the wrong MySQL plugin installed in your PHP. There are two versions: mysqlnd and libmysql. The second one used to cause so much trouble for me, because it returns data from database as strings even if the value is an actual integer. The mysqlnd is correctly returning the value as integer so if you use $model->id === 2 it will work correctly while with libmysql it will evaluate to false since it is strict check and $model->id will become string '2'. So this is what I would check your code against. Try to dump one of your roles ids and check if it is integer or string.

Upvotes: 1

Related Questions