Laravel Eloquent многие ко многим через другую таблицу с именем вместо id и получить дополнительные данные - PullRequest
1 голос
/ 18 января 2020

У меня есть две основные таблицы: сообщения и категории, которые должны иметь отношение «многие ко многим». Я знаю, что вы можете просто сделать это с таблицей под названием category_post, но это не то, как настроена структура, с которой я могу работать.

Это так: сообщения имеют отношение один к одному с у вопросов и вопросов есть категории в сообщениях.

Моя база данных выглядит следующим образом:

Schema::create('posts', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('title');
    $table->text('contet');
}

Schema::create('post_questions', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('post_id');
    $table->integer('views');
    $table->integer('answers');
}

Schema::create('categories', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('name')->unique();
}

Schema::create('post_question_categories', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->integer('post_question_id');
    $table->string('category_name');
    $table->string('additional_info');
}

Как видите, моя сводная таблица не имеет ни post_id, ни category_id, а post_question_id и имя_категории, которое является уникальным в таблице категорий. Но должно быть состояние «многие ко многим» с сообщениями и категориями.

Вопросы также имеют отношение «один ко многим» с запросом extra_infos

Это мои модели:

class Post extends Model
{
    public function question()
    {
        return $this->hasOne('App\PostQuestion')->with('categories');
    }
}

class Question extends Model
{
    public function post()
    {
        return $this->belongsTo('App\Post');
    }

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

class PostQuestionCategory extends Model
{
    public function question()
    {
        return $this->belongsTo('App\PostQuestion')->with('post');
    }
}

class Category extends Model
{
    public function posts()
    {

    }
}

Так вот где начинается самое интересное: я хочу запросить все сообщения из одной категории. Я уже попробовал и получил это 3 подходами:

1.

public function posts()
{
    $name = $this->name;

    return Post::whereHas('question', function ($question) use ($name) {
        $question->whereHas('categories', function ($categories) use ($name) {
            $categories->where('name', $name);
        });
    })->get();
}

2.

public function posts()
{
    return PostQuestionCategory::with('question')->where('name', $this->name)->get();
}

3. Добавление post_id и category_id в таблицу

public function posts()
{
    return $this->belongsToMany('App\Post', 'post_question_categories');
}

Третий вариант не является реальным, поскольку я не хочу манипулировать существующей базой данных. Во втором случае я не получаю объект post как отношение, а просто как простой результат запроса.

Также, когда я делаю это в категории / show.blade. php

@foreach ($category->posts() as $post)
   {{ $post->question->categories }}
@endforeach

Из-за этого у меня нет доступа ко многим атрибутам.

Поэтому я предпочитаю использовать первый вариант.

Дело в том:

Я хочу получить только категории, которые ток я в данный момент на. С этим запросом я получу действительно все сообщения, которые имеют это, но в foreach я также получу все дополнительные категории. Кроме того, я хочу получить в этом случае атрибут Additional_info.

Примерно так: я нахожусь на маршруте category.show/1 (name = cat1)

, а моя база данных выглядит как

записей

id   title
1    a
2    b
3    c
4    d

post_questions

id    post_id   views   answers
1     1         12      2
2     2         7       0
3     3         456     6
4     4         124     11

post_question_categories:

id  question_id   additional_info       category_name
1   1             ai1                   cat 1
2   1             ai2                   cat 2
3   3             ai1                   cat 1
4   4             ai1                   cat 3

категории

id  name
1   cat 1
2   cat 2
3   cat 3

Мой идеальный вывод будет:


posts 
[
    {id: 1, title: 'a', question: {id: 1, views: 12, answers: 2, categories: [{id: 1, additional_info: 'ai1', name: 'cat1'}, // Not id 2 since im on show/1]}, 
    {id: 3, title: 'c', question: {id: 3, views: 456, answers: 6, categories: [{id: 1, additional_info: 'ai1', name: 'cat1'}}
]

Надеюсь, это не слишком смущает, и кто-то может мне помочь!

1 Ответ

0 голосов
/ 18 января 2020

Я думаю, что ваш второй запрос уже решил вашу проблему. Просто внесите в него некоторые изменения, например:

public function posts()
{
    return PostQuestionCategory::with('question.post')->where('category_name', $this->name)->get();
}

, просто добавьте сообщение вместе с вопросом, чтобы иметь возможность включить его в возвращенную коллекцию.

или если у вас есть отношения также с категориями тогда вы просто добавляете также отношение категории, как это

 public function posts()
 {
        return PostQuestionCategory::with('question.post', 'category')->where('category_name', $this->name)->get();
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...