Laravel 5: 多対多、記事とタグの実装

WBOY
リリース: 2016-06-23 13:25:09
オリジナル
1348 人が閲覧しました

原文は https://laravist.com/article/18 からです

Laravist は私が立ち上げたばかりの Laravel コミュニティです。Laravel に関する質問があれば、ここに来て質問してください。問題を解決するのに役立つように、後でいくつかのビデオチュートリアルを録画してみます。フォーマットはおおよそ次のとおりです

https://laravist.com/lesson/1

Prelude

本文を始める前に、まず始めましょう。実際の開発における共通の連絡先について話す ここでは、いくつかの一般的な連絡先のパターンを示します:

One-To-One //一对一One-To-Many //一对多Many-To-Many //多对多
ログイン後にコピー

これらの概念をよく理解していない場合、あなたがどう感じているかわかりません。これらの概念は生活に適用でき、非常に簡単に理解できます。インターネットでよく見かける例を見てみましょう:

翻訳は次のとおりです:

1 つのユーザー プロファイルに対応します

1 人のユーザー複数の記事を公開できます

1 つの記事に複数のコメントを含めることができます

そして、記事とタグには多対多の関係があります。1 つの記事は複数のタグを持つことができ、1 つのタグは複数の記事に属することができます

これらの関係では、モデル内で。実装するのに最も難しいのは多対多の関係ですが、私たちの単純なブログにはユーザー管理がありません。つまり、ユーザー登録が公開されていないため、ここでもまだ難しいことに挑戦する必要があります。記事とタグの多対多の関係を実現するには、Laravel の強力な Eloquent の助けを借りてこの機能を実現するのが非常に満足です。 1 対 1 と 1 対多の 2 つの関係については、類似点を描くことができます。

タグテーブルを作成する

記事とタグの多対多の関係を実現するには、タグテーブルとタグモデルが必要なので、別々に作成します。

User-To-Profile // One-To-OneUser-To-Articles // One-To-ManyArticle-To-Comments // One-To-ManyArticles-To-Tags // Many-To-Many
ログイン後にコピー

生成された移行ファイルを開き、up() メソッドのコード行を追加します。

php artisan make:migration create_tags_table --create=tags
ログイン後にコピー

ここでは、 $table->string('name'); という行を追加しました。 as tags table ラベルの名前を表す名前フィールドを追加します。

次に、タグ テーブルのタグ モデルを作成します。

public function up(){  Schema::create('tags', function (Blueprint $table) {    $table->increments('id');    $table->string('name');    $table->timestamps();  });}
ログイン後にコピー

タグ モデルを生成した後は、Tag.php ファイルについて心配する必要はありません。リレーショナル テーブルarticle_tag も必要になるためです。 tag_idとarticle_idがあるので、それを作成しましょう:

php artisan make:model Tag
ログイン後にコピー

移行ファイルを開いて、tag_idとarticle_idの2つのフィールドを追加します:

php artisan make:migration create_article_tag_table --create=article_tag
ログイン後にコピー

ここに2つのフィールドtag_idとarticle_idが追加されているようですが、多くの行が含まれていますコードを理解する必要があるのは、次のことだけです:

rreee

foreign(): 外部キー

references(): 参照フィールド

on(): 参照テーブル

onDelete(): 削除時の実行アクション

ここたとえば、記事が削除されると、article_tag に同じarticle_id を含むレコードも削除されます

最後に、移行を実行して、article_tag テーブルを生成します:

 public function up()  {    Schema::create('article_tag', function (Blueprint $table) {      $table->increments('id');      $table->integer('article_id')->unsigned()->index();      $table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');      $table->integer('tag_id')->unsigned()->index();      $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');      $table->timestamps();    });  }
ログイン後にコピー

OK、これら 2 つのテーブルを生成した後、 、私たちは正式に仕事を始めることができます。

Eloquent 関係を宣言する

Article と Tags は多対多の関係であるため、Article.php で次の関係を宣言する必要があります:

$table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');
ログイン後にコピー

Tag.php でも同じです:

php artisan migrate
ログイン後にコピー

us $this->belongsToMany() を使用して Eloquent 関係を示します。ここで、外部キーがarticle_id と tag_id でない場合は、次のように記述して 3 番目のパラメーターに設定する必要があることに注意してください。

OK、これで多対多の関係が宣言されました。

Select2 を使用します

始める前に、tinker を使用していくつかのタグを生成します。最終的なプロセスは次のようになります。

次に、より良いユーザー エクスペリエンスを提供するために、Select2 を導入します。選択肢がたくさんあるので、オプションを選択したときのパフォーマンスは非常に完璧でした。

Select2 の使用法: https://select2.github.io/examples.html

app.blade.php で Select2 の css ファイルと js ファイルを紹介します:

public function tags()    {        return $this->belongsToMany('App\Tag');    }
ログイン後にコピー

In

導入後も、ファイル作成ページでフォームを使用して選択ボックスを生成できます。articles/create.blade.php ファイルに移動し、published_at の下に入力フォームを追加します。ここで注意してほしいのは、tag_list[] だけを使用する場合、複数のタグを選択する必要がある場合は、「複数」を指定することです。 =>「multiple」は、複数選択モードのサポートを有効にすることを意味します。 $tags はデータベースのタグ テーブルから取得する必要があるデータなので、当然のことながら、ArticleController の create() メソッドに移動して、コードを少し変更します。

这里我们使用lists()方法将Tag中(对于tags数据表)name和id以一个Eluqoent的方式返回,你可以使用dd($tags),来看看。恩,这个时候来看看我们的create页面:

这时候我们发现,样式并没有Select2那么好看,那是因为我们还没有初始化Select2,所以我们在create.blade.php写几行简单地js代码:

 <script type="text/javascript">        $(function() {            $(".js-example-basic-multiple").select2({                placeholder: "添加标签"            });        });    </script>
ログイン後にコピー

在 @endsection 紧接着的上一行加上上面的代码,这里我们使用jquery的选择器,然后调用 select2(); 来初始化我们的选择框,再来看看效果:

很完美,我们将整个UI完善得还不错,我们用 dd() ;来看看我们表单提交过来的是什么,在 ArticleController 中的 store() 方法中添加一行代码:

dd($request->all());
ログイン後にコピー

我们来看看效果:

我们看到得 tag_list 是一个数组,里面的值并不是我们选择的标签的 name ,而是标签的 id ,这样我们就可以使用laravel提供的 attach() 来添加我们的标签了,这个 attach() 接受一个id的数组,这里正好!,所以我们来稍微来修改一下 store() 方法:

 public function store(Requests\StoreArticleRequest $request)  {    $input = $request->all();    $input['intro'] = mb_substr($request->get('content'),0,64);    $article = Article::create($input);    $article->tags()->attach($request->input('tag_list'));    return redirect('/');  }
ログイン後にコピー

我们这里首先将 Article::create($input) 赋予 $article 变量(Eloquent对象),然后使用 $article->tags()->attach() 来添加标签,并将我们的标签数组传给 attach() 方法,我们来看看有没有成功:

这里的文章是发表成功了,我们再来看看我们的标签是否添加成功,来看看我们的 article_tag 表:

是添加了三个标签,但是我们发现这个 created_at 和 updated_at 貌似有点问题,我们来修复一下,在 Article.php 中的 tags() 方法中:

public function tags()    {        return $this->belongsToMany('App\Tag')->withTimestamps();    }
ログイン後にコピー

我们在后面直接使用 withTimestamps() 来同步我们的时间,我们再来试一试:

再来看看我们的数据库:

看到最后的两个记录,很完美。

在视图中显示我们的tags

我们既然有了标签,我们为什么不来将它展示出来呢?在 articles/index.blade.php 中,我们来将文件的标签输出一下:

<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>{{ $tag->name }}</li>    @endforeach  @endif</ul>
ログイン後にコピー

我们在

标签下面增加一个
    列表,然后是首先将发表日期 published_at 输出了,这里我们使用了Carbon的 diffForHumans() 方法,这个方法就会产生几分钟之前,几个小时之前的效果,这里也可以体会我们之前需要将 published_at 这个对象作为Carbon对象来对待了,如果是简单地字符串,是不能调用Carbon的 diffForHumans() 方法的。

    接下来,我们使用 $article->tags 取得文章的标签,这个 tags 就是我们声明多对多关系的 tags() 方法。我们来看看效果:

    我们发现 我们的多少分钟之前 都是英文,那是因为我们没有设置Carbon,我们来修复一下,在 app/Providers/AppServiceProvider.php 中的 boot() 方法添加下面这一行:

    \Carbon\Carbon::setLocale('zh');
    ログイン後にコピー

    然后刷新,见证一下奇迹吧:

    总结

    到这里我们利用laravel提供的 attach() 方法将基本的多对多关系实现了,并且还稍微美化了一下输出,将 published_at 字段完美呈现。


ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート