执行查询后修改相关模型的集合

时间:2016-06-16 22:56:38

标签: laravel collections laravel-5 eloquent

我从我的数据库中加载了一个模型和belongsToMany关系:

$author = Author::with('publications')->first();

/** Returns something like:

{
    "id": 3457,
    "email": "alex@trump.edu",
    "publications": {
        "1": {
            "id": 240897,
            "title": "Food left by other people at a restaurant - is it safe to eat?  A comparative review.",
            "journal": "Journal of Scrounging and Gleaning",
            "year": 2007,
            "pivot": {
                "author_id": 3457,
                "publication_id": 240897
            }
        },
        "2": {
            "id": 249196,
            "title": "Stop picking at it - you'll leave a scar!",
            "journal": "Proceedings of the International Conference on Nagging",
            "year": 2008,
            "pivot": {
                "author_id": 3457,
                "publication_id": 249196
            }
        }
    }
}

*/

然后,我从第三方API获取每个publication的一些额外数据,并将其合并到我的集合中,这可以正常工作。

但是,我想根据这个第三方数据对出版物进行排序,因此我在sortByDesc中使用回调:

$sorted = $author->publications->sortByDesc(function ($publication, $key) {
    // Blah blah blah not important how I sort
    return $blah;
});

$author->publications = $sorted->values();

根据sortBy的文档,如果我想在排序后重新编号我的结果,我需要使用values$sorted->values()确实似乎是一个重新键入的排序列表,但即使我将其分配给$author->publications$author->publications仍然有旧密钥。

更奇怪的是,即使我没有将结果分配回sortByDesc,只运行$author->publications似乎就地对列表进行排序。为什么我不能将重新加密的集合分配回$author->publications?我觉得这与关系与属性的细微差别有关,但我不知道如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

问题在于,当我将已排序的集合分配给$author->publication时,我实际上并没有覆盖关系 $author->publication。相反,我只是将新的属性添加到$author,这恰好也称为publication。因此,我的$author对象最终看起来像这样:

UserFrosting\Author Object
(
    [timestamps] => 
    [connection:protected] => 
    [table:protected] => author
    [primaryKey:protected] => id
    [perPage:protected] => 15
    [incrementing] => 1
    [attributes:protected] => Array
        (
            [id] => 3457
            [email] => alex@trump.edu
            [publications] => Illuminate\Database\Eloquent\Collection Object
                (
                    [items:protected] => Array
                        (
                            [0] => UserFrosting\Publication Object
                                (
                                    [timestamps] => 
                                    [connection:protected] => 
                                    [table:protected] => publication
                                    [primaryKey:protected] => id
                                    [perPage:protected] => 15
                                    [incrementing] => 1
                                    [attributes:protected] => Array
                                        (
                                            [id] => 240897
                                            [title] => Food left by other people at a restaurant - is it safe to eat?  A comparative review.
                                            [journal] => Journal of Scrounging and Gleaning
                                            [year] => 2007
                                        )
                                )
                            [1] => UserFrosting\Publication Object
                                (
                                    [timestamps] => 
                                    [connection:protected] => 
                                    [table:protected] => publication
                                    [primaryKey:protected] => id
                                    [perPage:protected] => 15
                                    [incrementing] => 1
                                    [attributes:protected] => Array
                                        (
                                            [id] => 249196
                                            [title] => Stop picking at it - you'll leave a scar!
                                            [journal] => Proceedings of the International Conference on Nagging
                                            [year] => 2008
                                        )
                                )                                
                        )
                )
        )

    [relations:protected] => Array
        (
            [publications] => Illuminate\Database\Eloquent\Collection Object
                (
                    [items:protected] => Array
                        (
                            [1] => UserFrosting\Publication Object
                                (
                                    [timestamps] => 
                                    [connection:protected] => 
                                    [table:protected] => publication
                                    [primaryKey:protected] => id
                                    [perPage:protected] => 15
                                    [incrementing] => 1
                                    [attributes:protected] => Array
                                        (
                                            [id] => 240897
                                            [title] => Food left by other people at a restaurant - is it safe to eat?  A comparative review.
                                            [journal] => Journal of Scrounging and Gleaning
                                            [year] => 2007
                                        )
                                )
                            [0] => UserFrosting\Publication Object
                                (
                                    [timestamps] => 
                                    [connection:protected] => 
                                    [table:protected] => publication
                                    [primaryKey:protected] => id
                                    [perPage:protected] => 15
                                    [incrementing] => 1
                                    [attributes:protected] => Array
                                        (
                                            [id] => 249196
                                            [title] => Stop picking at it - you'll leave a scar!
                                            [journal] => Proceedings of the International Conference on Nagging
                                            [year] => 2008
                                        )
                                )   
                        )
                )
        )
)

如您所见,relations包含已排序的发布列表,但仍保留原始密钥。 attributes包含已排序的重新编号的列表。当我调用$author->toArray()时,它显然使用 relation 而不是属性。因此,诀窍是强迫Eloquent assign my renumbered collection to the relation

$author->setRelation('publications', $sorted->values());