Eloquent Model с проблемой вложенной модели - PullRequest
0 голосов
/ 08 мая 2020

У меня есть пара таблиц, которые выглядят так:

1) article

  • id
  • name

2 ) article_options

  • id
  • article_id
  • option_id

3) option

  • id

  • name

В статье не может быть ни одного, одного или нескольких параметров, и я хочу вернуть в RestAPI структуру JSON, которая выглядит так:

[{
  "id": 1,
  "name": "Article1",
  "options": [10]
},
{
  "id": 2,
  "name": "Article2",
  "options": [3, 10]
},
{
  "id": 3,
  "name": "Article3",
  "options": []
}]

где 3 и 10 будут идентификаторами опций.

Я пробовал несколько решений, но ни одно из них не помогло. Вот то, что у меня сейчас есть:

Модель статьи:

class Article extends Model
{
#    protected $with = ['Article_Option'];

    public function options()
    {
        return $this->hasMany('App\Article_Option');
    }
}

Контроллер статьи:

class ArticleController extends Controller
{
    public function index()
    {
        $articles = Article::all();

        return response()->json(
            $articles
        , 200);
    }
}

Я просто не могу понять, как модель и контроллер должен быть настроен для достижения этой цели.

Пожалуйста, помогите.

Спасибо Goppi

[ОБНОВЛЕНИЕ]

Спасибо Hides Помогите. С некоторыми изменениями я заставил его работать так, как я хотел. Вот весь код ...

Модель статьи:

namespace App;
use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
  public function options()
  {
    return $this->belongsToMany('App\Option');
  }
}

ArticleController:

namespace App\Http\Controllers;
use App\Article;
use App\Http\Resources\Article as ArticleResource;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
  public function index()
  {
    $articles = ArticleResource::collection(Article::all());

    return response()->json ($articles, 200);
  }
}

и Ресурс:

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class Article extends JsonResource
{
  public function toArray($request)
  {
    return [
    'id' => $this->id,
    'name' => $this->name,
    'options' => $this->options->pluck('id')->all()
    ];
  }
}

1 Ответ

0 голосов
/ 08 мая 2020

article_options - это ваша сводная таблица, а связь между статьей и опциями - это отношение «многие ко многим», которое laravel предоставляет функцию для здесь . Итак, все, что вам нужно сделать, это добавить отношение к вашей модели article.

public function options() {
    return $this->belongsToMany(Option::class);
}

, тогда при получении статей вы можете назвать это отношение.

$articles = Article::with('options')->get();

Это будет захват все статьи со всеми связями опций и отформатируйте их так, как вам нужно. Laravel может автоматически определять, какие поля необходимо использовать для формирования связи между таблицами, поэтому не беспокойтесь об этом, хотя у него есть возможность предоставить их в функции belongsToMany.

Если вам нужен только идентификатор, который вы можете передать c столбцы в функцию with, как показано ниже.

$articles = Articles::with('options:id')->get()

Чтобы затем вернуться в формате json, вы можете использовать ресурсы . Ресурсы помогают лучше отформатировать коллекцию модели, которую можно использовать для достижения желаемого. Вам нужно будет создать ресурс для статей. В ресурсе статьи вы можете отформатировать его так, как вы хотите, и отформатировать параметры, которые вы можете использовать методы сбора, чтобы преобразовать его в массив идентификаторов, извлекая поле из коллекции.

Ресурс статьи

public function toArray($request)
{
    return [
       'id' => $this->id,
       'name' => $this->name,
       'options' => $this->options->pluck('id')->all(),
    ];
}

Итак, как только у вас есть статьи, вы можете вернуть их вот так

return new ArticlesResource::collection($articles);

Если позже вы захотите передать дополнительные столбцы для параметров, вы можете создать ресурс параметров и передать его в введите параметры в своем ресурсе статьи.

'options' => new OptionsResource::collection($this->options)
...