laravel 4 Eager load as a list of ids

拜拜、爱过 提交于 2019-12-23 04:25:01

问题


I would like to make eager load of a related model. however, instead of getting the whole related model, i'd like to retrieve just its id. so at the end, i'll have something like the following:

{
"error": false,
"invoices": {
    "id": 5,
    "biz_id": 7,
    "doc_num": 0,
    "type": 1,
    "due_date": "0000-00-00",
    "status": null,
    "to": null,
    "**related_model**": [1,2,3,4]
}

I'd prefer avoiding loops.

UPDATE

as I understand I couldn't make it without loops, i have done the following:

        $data = array();
    //get models
    $models = IncomeDoc::with('relatedReceipts')
                        ->where('type', '!=', 2)
                        ->get()
                        ->toArray();

    foreach ($models as $model)
    {
        $model['related_receipts'] = array_pluck($model['related_receipts'], 'id');

        $data[] = $model;
    }

Now here is my question: is there any way that i could do that data manipulation in the model itself? this code is not clean and can not be re-used, and i'd rather avoid it.


回答1:


You can use the relationship to get the identifiers.

  1. Custom function:

    public function myRelationIds()
    {
        return $this->myRelation->lists('id');
    }
    

    You call the function and add the results to the response.

  2. Through accessor

    public function getMyRelationIdsAttribute()
    {
        return $this->myRelation->lists('id');
    }
    

    Now, you can make this attribute is automatically added when the model becomes Array or JSON with appends property:

    protected $appends = array('my_relation_ids');
    

Note that it's important to continue eager loading relation to prevent excessive queries. And given that the relationship will continue loading, you might want to hide it and only have identifiers:

protected $hidden = array('myrelation');



回答2:


The very straight solution would be to define visible fields in your related model:

class RelatedModel extends Eloquent
{
    protected $visible = array('id');
}

Note, this would be the only field returned by toArray() method everywhere.




回答3:


Directly you won't be able to get all the ids in a single model, each model will have it's own related models but you may get the related model's ids using something like following, for example Post is main/parent model and Post has many comments, so it could be done using this:

$ids = array();
$posts = Post::with(array('comments' => function($q){
    // post_id is required because it's the foreign key for Post
    $q->select(array('id', 'post_id'));
}))->get()->map(function($item) use(&$ids){
    $ids[] = $item->comments->fetch('id')->toArray();
});

// Get all ids in one array
$ids = array_flatten($ids);

Now, you just rename the Post with Invoice and comments with related model name. Here Post has many comments with following relation defined in the Post model:

// Post model
public function comments()
{
    return $this->hasMany('Comment'); // Comment model
}



回答4:


I was having some problems with eager loading recently myself. My suggestion is to just replicate what eager loading does, which is run a second query including a whereIn() of the ids from the first model. Going back to your example

$modelsQuery = IncomeDoc::where('type', '!=', 2);
$models = $modelsQuery->get();
$modelIds = $models->select('id')->lists('id');
$relatedReceiptsQuery = RelatedReceipts::whereIn(`model_id`,$modelIds);
$relatedReceipts = $relatedReceiptsQuery->get();
$relatedReceiptsLookup = $relatedReceiptsQuery->lists(`id`,`model_id`)

You'll be able to iterate through $models, and retrieve $relatedReceipts->find($relatedReceiptsLookup[$models->id]). You could simplify this further if you only want a single field from RelatedReceipts, or you could probably add toArray() to $relatedReceipts and search the array instead of using $relatedReceiptsLookup to search the models.



来源:https://stackoverflow.com/questions/22802670/laravel-4-eager-load-as-a-list-of-ids

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!