Laravel:在父表上与 *where* 建立雄辩的关系,而不是 *find*

Posted

技术标签:

【中文标题】Laravel:在父表上与 *where* 建立雄辩的关系,而不是 *find*【英文标题】:Laravel: Eloquent relationships with *where* on parent table instead of *find* 【发布时间】:2018-07-19 00:44:40 【问题描述】:

我有一张桌子postsposts_contents。 而且我只想从一个帖子中获取内容,前提是该帖子具有display = 1

(由于语言支持,我需要两个单独的表格)

帖子:

id  user_id  display

1   2        0
2   2        1
3   2        0
4   2        1

posts_contents

id  post_id  lang_id  name    description

1   1        1        Hello   World
2   2        1        Here    Is What I wanna show!
3   3        1        Don't   Show the others
4   4        1        Hey     Display that one too

所以在 laravel 中我使用了雄辩的关系,但我只是不明白如何在这种特殊情况下使用它。在文档中,我发现只有以下情况:

$p = App\Posts::find(1)->contents;

效果很好,但是我想要的是这样的:

$p = App\Posts::where('display',1)->contents;

但它不起作用......所以问题是:这样做的正确方法是什么?

感谢任何帮助,谢谢!

更新

我需要同时获得多个帖子,而不仅仅是一个。

【问题讨论】:

@ka_lin 是可选的 【参考方案1】:

你想像这样使用find() 方法:

$post = App\Posts::where('display', 1)->find($postId)->contents;

那么在一对一关系的视图中:

 $post->description 

对于一对多:

@foreach ($post->contents as $content)
     $content->description 
@endforeach

如果您想加载仅包含一种语言内容的多个帖子,请使用按语言过滤。使用with() 到eager load 内容:

$posts = App\Posts::where('display', 1)
    ->with(['contents' => function($q) use($langId) 
        $q->where('lang_id', $langId);
    ])
    ->get();

然后在视图中进行一对一:

@foreach ($posts as $post)
     $post->contents->description 
@endforeach

对于一对多:

@foreach ($posts as $post)
    @foreach ($post->contents as $content)
         $content->description 
    @endforeach
@endforeach

您可以阅读find()get() 方法here 之间的区别。

【讨论】:

太棒了!如何使用app('locale') 而不是$langId @MaxMaximilian 这只是一个示例,因此您应该使用真实 ID。如果app('locale') 返回类似2 的ID,则可以使用它。如果它返回类似en 的东西,你需要做一些不同的事情。 是的,我现在正在考虑,你是对的。惊人的!这正是我所需要的!【参考方案2】:

在调用任何关系之前,您需要调用first 方法:

$p = App\Posts::where('display', 1)->first()->contents;

或者,如果您想获取帖子集合,您可以:

$posts = App\Posts::where('display', 1)->get();

$posts->each(function ($post) 
    $post->contents;
);

否则,您将只有一个 Query Builder 对象,而没有您想要的实际结果。

【讨论】:

【参考方案3】:

App\Posts::where 将返回一个集合。所以如果你只想要 1 个结果,你应该使用 App\Posts::where('display',1)->first()->contents

【讨论】:

好! first 会返回什么? 它将查询更改为使用 1 个结果的限制。因此,Eloquent 将只返回对象(来自 Posts 类)而不是对象集合。 (有点像来自 laravel 的数组) 嗯,我怎样才能获得多行内容呢?使用joins 似乎有点棘手...... 我所说的集合是“多行”,您只需将它们循环以逐一获取其内容

以上是关于Laravel:在父表上与 *where* 建立雄辩的关系,而不是 *find*的主要内容,如果未能解决你的问题,请参考以下文章

在父表上存储 1:N 关系中的特定列

Laravel:在父表上用*表示*而不是* find *的雄辩关系

mysql外键说明

mysql设置外键

更新子表后数据库触发器更新父表上的行

MySQL外键设置中的的 CascadeNO ACTIONRestrictSET NULL