根据标签分类列出所有含有包含改标签的文章

先说一下我想要完成的功能,想完成的功能就是点击一个标签的时候可以将包含有该标签的所有文章列出来。

就比如说博主本站中点击任何一个laravel标签就进入这个laravel标签页

我的文章和标签都是按照博主的标签来做的(Laravel教程 九:Eloquent Relationship

但是我发现自己的文章展示页面是这样查询的

public function show($id)
    {
        $tag = Tag::findOrFail($id);
        return view('tags.show',compact('tag'));
    }

怎样可以根据标签的名称来查询?比如说查找github、laravel等标签

求指导

首先你在tags表的时候,最好确定tag的name字段是唯一的。然后,你如果成功建立了tagarticle的关系,也就是第三张article_tag表,然后查询的时候:

public function showArticleByTag($name)
    {
        $tag = Tag::where('name','=',$name)->first();
        $articles = $tag->articles;
        // $tag->articles的articles就是对应的relationship;
}

routes大概是这样的:

Route::get('/article/tags/{name}','TagsController@showArticleByTag');

图片上传是用的这个

http://www.dropzonejs.com/

Kirits

@Jelly 顺便问一下你的图片上传是怎样实现的,很漂亮!

JellyBool

首先你在tags表的时候,最好确定tag的name字段是唯一的。然后,你如果成功建立了tagarticle的关系,也就是第三张article_tag表,然后查询的时候:

public function showArticleByTag($name)
    {
        $tag = Tag::where('name','=',$name)->first();
        $articles = $tag->articles;
        // $tag->articles的articles就是对应的relationship;
}

routes大概是这样的:

Route::get('/article/tags/{name}','TagsController@showArticleByTag');

图片上传是用的这个

http://www.dropzonejs.com/

JellyBool

@Kirits 还有不明白的地方可以继续问我

blackmirror
  • 创建一张标签表,包括idlab_name
  • article表,加入art_lab_id字段
  • 用的时候两张表left join就可以了。
JellyBool

我还是觉得三张表是更好的解决方案,你这样的两张表其实对于多对多会出现很多数据冗余 @blackmirror

blackmirror

@JellyBool 忘记是多对多了。博主好厉害。

JellyBool

要学的东西还很多,一对多得话就是这种典型的解决方案 @blackmirror

blackmirror

@JellyBool 我们公司用的是逗号。关系表给扔到一边了。当时我做的时候,费了好大劲儿。不知道为什么有关系表却不用。。。

JellyBool

好的吧?用,是会用到in()查询? @blackmirror

blackmirror

@JellyBool 用的是like。。、、in只能针对结果集和单个字段字符串吧,多个用逗号隔开的是不行的。

JellyBool

好的吧,我以为是这种:

select columes from tags where id in (id1,id2,id3);

我以为你们是这样存id1,id2,id3。长见识了 @blackmirror

blackmirror

@JellyBool 这种方法很不好。。

JellyBool

用like我觉得简直了。。。 @blackmirror

blackmirror

@JellyBool 因为没想到别的方法啊。。。关系表又没有启用。。

Kirits

@JellyBool 一直查其他资料,忘记来看了,我看看先

JellyBool

好的吧 @blackmirror

JellyBool

看嘛 @Kirits

Kirits

当我的代码是这样的时候:

public function showArticleByTag($name)
    {
		$tag = Tag::where('name','=',$name)->first();
		$articles = $tag->articles;
		// $tag->articles的articles就是对应的relationship;
		//return view('tags.show',compact('articles'));
		dd($tag);
		//dd($articles);
	}

是可以输出数据的:

但是代码是这样的时候:

public function showArticleByTag($name)
    {
		$tag = Tag::where('name','=',$name)->first();
		$articles = $tag->articles;
		// $tag->articles的articles就是对应的relationship;
		//return view('tags.show',compact('articles'));
		//dd($tag);
		dd($articles);
	}

却显示null;
然而我是确认过一对多关系的:

JellyBool
$tag->article

Kirits

@JellyBool 粗心了,可以了

Kirits

@JellyBool 灰常感谢

JellyBool

哈哈哈,解决了就好 @Kirits

JellyBool

你点评论右下角的钩钩,将我的第一个评论设为答案试试。。。貌似这个功能还没有其他人测试过。。 @Kirits

Kirits

不过不知道为什么排版如此简单lol,用的模板是和文章展示页面一样的,

然而文章页面正常:

Kirits

@JellyBool 点了勾,但是页面好像没什么变化

Kirits

@JellyBool 还是觉得消息提示应该改一下,比如说我发了这张贴,别人发表了一条评论,我会有两条消息提醒,但是点进来的时候,应该同时消去指向同一条评论的消息,你觉得这样如何?

Kirits

又出现了一个很苦恼的问题,弄了10几分钟弄不出来
我将article/tags改成了articles/tags

结果就

我的Tagscontroller:

JellyBool

将框框中的两条路由放到/articles/{id}路由上面,因为你这样是首先解析了第一条路由,/articles/tagstags作为变量id传入了show()方法,所以会出现这个错。

JellyBool

关于消息提示,我优化一下。。。

openwrtmail

真的可以考虑做一个Category 分类。文章多了 揉在一起不方便索引

Kirits

@JellyBool 页面排版又是什么问题?

Kirits

@JellyBool 将你这句话读了几遍还是有点不明白,先解析的是上面的路由的话,/article/tags还是在’article/tags/{name}上面啊,这样的话跟article/{id}有什么关联?

JellyBool

/article/tags它就解析到这个article/{id}

排版你看看开发者工具,有没有加载到对应的css文件

JellyBool

分类还不会做吧,其实标签分类就很好了,何况平时其他站点的分类基本就是依赖标签
@openwrtmail

JellyBool

不明白的话我视频会讲解,现在只要讲他们移上去应该就解决问题了

BTW,写PHP,特别是用框架,建议使用PhpStorm @Kirits

Kirits

@JellyBool 好的,下了phpstorm,但不太会用

Kirits

不知道为什么tags/show.blade.php并没有嵌套在articles.blade.php

代码跟articles/show.blade.php一样的,@endsection完整

JellyBool

虽然说是可以传照片,但是这种情况还是希望直接上代码好一点,就是将这个页面的blade源码放上来 @Kirits

Kirits
@extends('articles')
@section('content')
      @foreach($articles as $article)
<article class="format-image group">
    <h2 class="post-title pad">
    <a href="/articles/{ $article->id }"> { $article->title }</a>
    </h2>
    <ul class="post-meta pad group">
        <li><i class="fa fa-clock-o"></i>{ $article->published_at->diffForHumans() }</li>
        @if($article->tags)
            @foreach($article->tags as $tag)
                <li><i class="fa fa-tag"></i><a href="/articles/tags/{ $tag->name }">{ $tag->name }</a></li>
            @endforeach
        @endif
        <li><i class="fa fa-eye"></i>{ count($article->visitors) } 浏览</li>
        <li><i class="fa fa-comments"></i><a target="_blank" href="##">{ count($article->comments) } 评论</a></li>
    </ul>
    <div class="post-inner">
        <div class="post-deco">
            <div class="hex hex-small">
                <div class="hex-inner"><i class="fa"></i></div>
                <div class="corner-1"></div>
                <div class="corner-2"></div>
            </div>
        </div>
        <div class="post-content pad">
            <div class="entry custome">
                { $article->intro }
            </div>
            <a class="more-link-custom" href="/articles/{ $article->id }"><span><i>更多</i></span></a>
        </div>
    </div>
</article>
     @endforeach
       <!--{!! $articles->render() !!}-->
@endsection

articles.blade.php是存在的,因为views/articles/index.blade.php是可以正常显示的

JellyBool

articles.blade.php这是什么,@extends('articles')这个你确定加载css?

articles.blade.php是存在的,因为views/articles/index.blade.php是可以正常显示的这两个貌似看不出有什么关联性

Kirits

article.blade.php是页面展示的布局,在views/文件夹根目录下
article.blade.php:

<html class="no-js" lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>Articles</title>
    <link rel='stylesheet' href="/css/all.css" type='text/css' media='all'/>
    <script type='text/javascript' src="/js/all.js"></script>
    <link rel='stylesheet' href="/css/bootstrap.min.css" type='text/css' media='all'/>
    <link rel='stylesheet' href="/css/select2.css" type='text/css' media='all'/>
    <script src="/js/jquery-2.1.4.min.js"></script>
    <script src="/js/select2.min.js"></script>
    <script src="/js/bootstrap.min.js"></script>
</head>
<body>
<div id="wrapper">
        <div class="container">
            <section class="content">
                <div class="pad group">
                    @yield('content')
                </div>
            </section>
        </div>

    <nav class="nav-container group" id="nav-footer">
        <div class="nav-wrap">
            <ul class="nav container group">
                <li class="menu-item">
                    <a href="/" rel="nofollow" target="_blank">Laravel 5 Blog</a>
                </li>
            </ul>
        </div>
    </nav>
</div>
</body>
</html>

因为views/articles/index.blade.php的代码是跟tags/show.blade.php的代码一样的
tags/show.blade.php

<!DOCTYPE html>
<html class="no-js" lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>Articles</title>
    <link rel='stylesheet' href="/css/all.css" type='text/css' media='all'/>
    <script type='text/javascript' src="/js/all.js"></script>
    <link rel='stylesheet' href="/css/bootstrap.min.css" type='text/css' media='all'/>
    <link rel='stylesheet' href="/css/select2.css" type='text/css' media='all'/>
    <script src="/js/jquery-2.1.4.min.js"></script>
    <script src="/js/select2.min.js"></script>
    <script src="/js/bootstrap.min.js"></script>
</head>
<body>
<div id="wrapper">
        <div class="container">
            <section class="content">
                <div class="pad group">
                    @yield('content')
                </div>
            </section>
        </div>

    <nav class="nav-container group" id="nav-footer">
        <div class="nav-wrap">
            <ul class="nav container group">
                <li class="menu-item">
                    <a href="/" rel="nofollow" target="_blank">Laravel 5 Blog</a>
                </li>
            </ul>
        </div>
    </nav>
</div>
</body>
</html>
Kirits

啊啊啊,发现上面好多复制错了,可惜不能改,重新发一份,上面的方便的话删了都可以。
articles.blade.php是页面展示的布局,在views/文件夹根目录下
articles.blade.php:

<!DOCTYPE html>
<html class="no-js" lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>Articles</title>
    <link rel='stylesheet' href="/css/all.css" type='text/css' media='all'/>
    <script type='text/javascript' src="/js/all.js"></script>
    <link rel='stylesheet' href="/css/bootstrap.min.css" type='text/css' media='all'/>
    <link rel='stylesheet' href="/css/select2.css" type='text/css' media='all'/>
    <script src="/js/jquery-2.1.4.min.js"></script>
    <script src="/js/select2.min.js"></script>
    <script src="/js/bootstrap.min.js"></script>
</head>
<body>
<div id="wrapper">
        <div class="container">
            <section class="content">
                <div class="pad group">
                    @yield('content')
                </div>
            </section>
        </div>

    <nav class="nav-container group" id="nav-footer">
        <div class="nav-wrap">
            <ul class="nav container group">
                <li class="menu-item">
                    <a href="/" rel="nofollow" target="_blank">Laravel 5 Blog</a>
                </li>
            </ul>
        </div>
    </nav>
</div>
</body>
</html>

因为views/articles/index.blade.php的代码是跟tags/show.blade.php的代码一样的
views/articles/index.blade.php的代码:

@extends('articles')
@section('content')
      @foreach($articles as $article)
<article class="format-image group">
    <h2 class="post-title pad">
    <a href="/articles/{ $article->id }"> { $article->title }</a>
    </h2>
    <ul class="post-meta pad group">
        <li><i class="fa fa-clock-o"></i>{ $article->published_at->diffForHumans() }</li>
        @if($article->tags)
            @foreach($article->tags as $tag)
                <li><i class="fa fa-tag"></i><a href="/articles/tags/{ $tag->name }">{ $tag->name }</a></li>
            @endforeach
        @endif
        <li><i class="fa fa-eye"></i>{ count($article->visitors) } 浏览</li>
        <li><i class="fa fa-comments"></i><a target="_blank" href="##">{ count($article->comments) } 评论</a></li>
    </ul>
    <div class="post-inner">
        <div class="post-deco">
            <div class="hex hex-small">
                <div class="hex-inner"><i class="fa"></i></div>
                <div class="corner-1"></div>
                <div class="corner-2"></div>
            </div>
        </div>
        <div class="post-content pad">
            <div class="entry custome">
                { $article->intro }
            </div>
            <a class="more-link-custom" href="/articles/{ $article->id }"><span><i>更多</i></span></a>
        </div>
    </div>
</article>
	   @endforeach
       {!! $articles->render() !!}
@endsection
Kirits

我重新将views/articles/index.blade.phptags/show.blade.php里面,反而可以了,好无语 ==,这问题不知道怎么就解决了

JellyBool

如果是这样的话:views/article.blade.php,那么应该@extends('article')

看看这个 https://laravist.com/article/11

JellyBool

额,好吧,不知道你整个视图是怎么管理的,你明白了blade的继承没有

Kirits

@JellyBool 好的,这个知道,已经解决啦

Kirits

@JellyBool 明白啦,之前继承不知道哪里出问题了

JellyBool

OK,不过很有进步,就是希望这种讨论。。。用markdown代码块,很完美。所以上代码比照片好。。

Kirits

哈哈,知道了

JellyBool

挺好的,哎,我还是来写写评论分页吧。不然太辛苦了,哈哈哈

Kirits

@JellyBool 哈哈,支持支持

xoolee

我下午看了一下午没有弄出哪里错了

model 表

public function belongsToManyPosts()
    {
        return $this->belongsToMany('App\Post', 'relationships', 'meta_id', 'post_id');
    }

tag controller

$tag = Meta::where('meta_slug', $slug)->where('meta_type', $type)->get();
$posts = $tag->belongsToManyPosts()->get();
return $posts;

访问 app/tag/slug 提示 belongsToManyPosts 方法不存在

@JellyBool

xoolee

Method belongsToManyPosts does not exist.

但是我进入 tinker 里面用同样的语句 可以查询到文章的啊 晕死

@JellyBool