【问题标题】:Laravel Eloquent Many to Many through other table with name instead id and get additional dataLaravel Eloquent 多对多通过名称而不是 id 的其他表并获取其他数据
【发布时间】:2020-05-05 03:22:47
【问题描述】:

我有两个主表,帖子和类别,它们应该具有多对多关系。 我知道你可以使用一个名为 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 和 category_name,这在 categories 表中是唯一的。但应该是状态是多对多的帖子和类别。

问题也与查询附加信息具有一对多关系

这是我的模型:

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 对象作为一个关系,而只是作为一个普通的查询结果。

当我在 category/show.blade.php 中做时

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

因此,我无法访问许多属性。

所以我更喜欢使用第一个选项。

事情是这样的:

我只想获取我当前所在的类别。 通过该查询,我确实会获得所有具有该查询的帖子,但在 foreach 中,我还将获得所有其他类别。 此外,我想在此实例中获取 additional_info 属性。

像这样: 我在路线 categories.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'}}
]

我希望这不会太混乱,有人可以帮助我!

【问题讨论】:

  • 其实,由于分类虽然是多对多的,但在这篇文章中只能找到一次,如果分类不是数组而是单个对象,输出会更好
  • PostQuestionCategory 应该扩展 Pivot(即不是模型)。
  • 为什么在您的 post_question_categories 中,您只使用类别名称而不是 id 本身?比如 category_id = 类别 ID

标签: php laravel eloquent orm many-to-many


【解决方案1】:

我认为您的第二个查询已经解决了您的问题。只需像这样对其进行一些修改。

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();
 }

【讨论】:

  • 是的,没错,我有正确的方法,但直到最后才想到。我只需要正确使用我在这个输出数组中获得的大量数据,我就拥有了我需要的一切。
  • 其实不用说 with('question.post') 因为我在 PostQuestionCategory 类中的问题功能已经做到了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 1970-01-01
  • 2022-01-19
  • 2021-03-26
  • 1970-01-01
  • 2018-06-01
  • 2011-02-25
相关资源
最近更新 更多