Я хотел бы получить активную нагрузку на связанную модель. однако вместо того, чтобы получить всю связанную модель, я бы хотел получить только ее идентификатор. поэтому в конце у меня будет что-то вроде следующего:
{ "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] }
Я бы предпочел избегать циклов.
ОБНОВИТЬ
как я понимаю, я не мог сделать это без циклов, я сделал следующее:
$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; }
Теперь вот мой вопрос: есть ли способ, которым я мог бы манипулировать данными в самой модели? этот код не является чистым и не может быть повторно использован, и я бы предпочел избежать его.
Вы можете использовать эту связь для получения идентификаторов.
Пользовательская функция:
public function myRelationIds() { return $this->myRelation->lists('id'); }
Вы вызываете функцию и добавляете результаты в ответ.
Через аксессуар
public function getMyRelationIdsAttribute() { return $this->myRelation->lists('id'); }
Теперь вы можете сделать этот атрибут автоматически добавленным, когда модель станет Array или JSON с appends
свойства:
protected $appends = array('my_relation_ids');
Обратите внимание, что для предотвращения чрезмерных запросов важно продолжать активное отношение загрузки. И учитывая, что отношения будут продолжать загружаться, вы можете скрыть это и иметь только идентификаторы:
protected $hidden = array('myrelation');
Очень правильным решением было бы определить видимые поля в вашей связанной модели:
class RelatedModel extends Eloquent { protected $visible = array('id'); }
Обратите внимание, что это будет единственное поле, возвращаемое методом toArray()
всем мире.
Непосредственно вы не сможете получить все id
в одной модели, каждая модель будет иметь свои собственные связанные модели, но вы можете получить id
связанной модели, используя что-то вроде следующего, например Post
– главная / родительская модель и Post
имеет много comments
, поэтому это можно сделать, используя следующее:
$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);
Теперь вы просто переименовываете Post
с помощью Invoice
и comments
с соответствующим именем модели. Здесь Post
имеет много комментариев со следующим соотношением, определенным в модели Post
:
// Post model public function comments() { return $this->hasMany('Comment'); // Comment model }
В последнее время у меня были проблемы с нетерпением. Мое предложение состоит в том, чтобы просто повторить то, что делает whereIn()
загрузка, в которой выполняется второй запрос, включая whereIn()
идентификаторов из первой модели. Вернемся к вашему примеру
$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`)
Вы сможете выполнить итерацию через $models
и получить $relatedReceipts->find($relatedReceiptsLookup[$models->id])
. Вы можете упростить это, если хотите только одно поле из RelatedReceipts
или вы можете добавить toArray()
в $relatedReceipts
и искать массив, а не использовать $relatedReceiptsLookup
для поиска моделей.