【问题标题】:Laravel 5.5, Display news data from two tablesLaravel 5.5,显示来自两个表的新闻数据
【发布时间】:2017-12-20 20:26:13
【问题描述】:

我是 laravel 的新手,遇到了一些麻烦。我尝试获取存储在两个不同表中的数据并显示它们:

News.php(模型)

    public static function Data($category) {
    $perPage = config('var.news.perPage');

    if ($category) {
        $news = News::orderBy('id', 'desc')->where('category', $category)->SimplePaginate($perPage);
    } else {
        $news = News::orderBy('id', 'desc')->SimplePaginate($perPage);
    }

    return $news;
}

这就是我从结构是的 News 表中获取所有数据的方式:

id, title, body, created_at updated_at, created_by, updated_by, category

类别列包含以逗号分隔的值,例如1,2,3,4

现在,我有另一个表 News_Cat,它有 id, name 列。

在另一种方法中,我尝试根据存储在新闻表的类别列中的值来获取过滤器名称

    public static function getFilterNames($id) {

    $filters = DB::table('News_Cat')
        ->select('News_Cat.name as name')
        ->leftJoin('News', DB::raw('CAST(News_Cat.id as nvarchar)'), DB::raw('ANY(SELECT(News.category))'))
        ->where('News.id', $id)
        ->get();

    return $filters;
}

但是,它完全不起作用。我试图实现的是在 view.blade 中将过滤器名称显示为来自 News_Cat 的指定过滤器的“名称”值

            @if($news->count())
        @foreach($news as $article)
        <a href="{{ route('news.show', $article->id) }}" class="item angled-bg" data-filters="{{ $filters }}">
            <div class="row">

所以结果我会得到例如data-filters="news, update, hot, latest"&gt; 改为 data-filters="1,2,3,4">

谢谢

【问题讨论】:

    标签: sql laravel


    【解决方案1】:

    你应该使用雄辩的!

    在您的新闻模型中

    public function getFiltersAttribute(){
           $categories = explode(',', $this->category);
           return implode(', ', NewsCat::find($categories)->pluck('name')->toArray());
    }
    

    那么在你看来:

    {{ $article->filters }}
    

    将输出news, update, hot, latest

    但是

    您应该在类别和新闻之间使用数据透视表,这样会容易得多。 这种方法不能让你急切地加载关系并为每条新闻发出请求

    如果你不能改变你的数据库结构,我可以建议你:

    在你的 AppServiceProvider 的启动方法中:

    Config::set('tags', NewsCat::all());
    

    那么

    public function getFiltersAttribute(){
           $categories = explode(',' $this->category);
           return implode(', ', config('tags')->whereIn('id', $categories)->pluck('name')->toArray());
    }
    

    多对多方法

    我正在为表格使用 laravel 命名约定:

    新闻、categories_news(枢轴)和类别

    您将拥有 2 个模型:New 和 Category

    在您的新模型中

    public function categories(){
        return $this->belongsToMany(Category::class)
    }
    

    在您的类别模型中:

    public function news(){
        return $this->belongsToMany(New::class);
    }
    

    如果您不使用 laravel 命名约定,则必须像这样自定义这些关系:https://laravel.com/docs/5.5/eloquent-relationships#many-to-many

    【讨论】:

    • 感谢您的回复,我将尝试您的建议。理论上我可以改变结构,但它需要 3 个我想要避免的表,例如- News - NewsType - NewsCat,其中 NewsType 将存储可用新闻类型的列表,而 NewsCat 将存储每个新闻的每种类型的条目。在这种情况下,NewsCat 将无限增长,因为每个新闻的条目数量与分配给新闻的类型一样多。或者有更好的建议?
    • 您将有 3 个表:news、categories_news(数据透视表)和类别 是的,数据透视表可能会增长得很快,但不要担心!这就是数据库的设计:),无论如何你永远不会请求整个表!检索属于一个类别的所有新闻将更加容易!作为最佳实践,切勿在数据库中以非关系方式存储关系信息
    • 我尝试了您之前的建议并且它有效,因此我将其标记为正确答案(您只是错过了爆炸中的命令)。但是,我想我决定去 3 张桌子。你能否给我一个线索如何在 Laravel 中的 3 个表之间建立连接 - 当然是代码部分 - 我正在考虑使用 BelongsToMany ..?这个框架在某些方面对我来说仍然很神奇。提前谢谢你
    • 这一切看起来如此简单,以至于我问我感到很惭愧,但我已经能理解事情了!除了一个.. 在我们使用 implode/explode 的情况 1 中:{{ $article->filters }} “过滤器”来自哪里?!。在您的代码中,没有在任何范围内定义过滤器词,为什么在进行爆炸/内爆后它在“$article->”中可用?
    • 它来自 getter : getFiltersAttribute(),你可以阅读这个以获得更多信息:laravel.com/docs/5.5/eloquent-mutators#defining-an-accessor
    猜你喜欢
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 2016-08-30
    • 2014-10-15
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多