SHIRANGANA Laravel5.1 collectionの注意点 忍者ブログ
エンジニア日記
Admin / Write
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

Laravel小ネタ。

Laravelで用意されている便利な配列操作オブジェクト「collection」
これを使用している中で、人によってはハマりそうなケースを発見しました。

こんなことがあったのです

// EloquentのCollectionをゲット。
$persons = App\Person::all();

// あるカラムだけのCollectionにして、重複を排除してみよう。
$nicknames = $persons->pluck('nickname')->unique();

( ゜Д゜)あれー

[Symfony\Component\Debug\Exception\FatalThrowableError]
Fatal error: Call to a member function getKey() on integer

普通に重複を排除した値を取ってくれるなら問題ないんですが
エラーで落ちてしまいました。

とりあえず結論から

Eloquentから得たCollectionは
「Illuminate\Database\Eloquent\Collection」
を使っている。

実はこれ、Illuminate\Support\Collection と似ているが、ちょっと違う。
このオブジェクトは所属アイテムがEloquentのModelオブジェクトである事を想定しているようだ!

よって、pluck()等でEloquentオブジェクト以外が所属している状態になった場合は
使うメソッドによっては、エラーになるぞ!

エラーの解決策

Modelのcollectionとして使用しないのなら、混同しないこと。
明示的にIlluminate\Support\Collection オブジェクトにして扱えばよろしい。

    $nicknames = collect($persons->pluck('nickname'))->unique();

ちなみに

エラーが発生した場所のコードはこちら。

/**
 * Return only unique items from the collection.
 *
 * @param  string|callable|null  $key
 * @return static
 */
public function unique($key = null)
{
    if (! is_null($key)) {
        return parent::unique($key);
    }

    return new static(array_values($this->getDictionary()));
}

からの、

/**
 * Get a dictionary keyed by primary keys.
 *
 * @param  \ArrayAccess|array  $items
 * @return array
 */
public function getDictionary($items = null)
{
    $items = is_null($items) ? $this->items : $items;

    $dictionary = [];

    foreach ($items as $value) {
        // ここ!!$itemにgetKey()が実装されている事が前提になっている。
        // getKeyは、Eloquent Modelのプライマリキーのカラム名を返すメソッド。
        $dictionary[$value->getKey()] = $value;
    }

    return $dictionary;
}

Laravelはソースがきれいなのですぐ分かります。
なるほどね、と思ったのでした。

PR
この記事にコメントする
Name :
Title :
Mail :
URL :
Color :   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
Comment :
Password :
HOME | 28  27  25  18  16  13  10  7  5 

忍者ブログ [PR]