ホームページ  >  記事  >  バックエンド開発  >  Laravel 5 チュートリアル シリーズ 9: 雄弁な関係

Laravel 5 チュートリアル シリーズ 9: 雄弁な関係

WBOY
WBOYオリジナル
2016-06-23 13:26:451097ブラウズ

原文は https://laravist.com/article/18 より

Laravist は私が立ち上げた Laravel コミュニティです。Laravel に関する質問がある場合は、ここに来て質問してください。問題を解決するのに最適です。後でいくつかのビデオチュートリアルを録画してみます。形式はおそらく次のとおりです

https://laravist.com/lesson/1

前奏曲

本文を始める前に、最初に、実際の開発でよく起こることについて話します。私は、いくつかの一般的な対応パターンに遭遇しました。

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'); という行を追加しています、このフィールドは名前フィールドを追加することを意味しますタグテーブルへの、ラベルの名前を表します。

    次に、タグ テーブルのタグ モデルを作成します。
  • public function up(){    Schema::create('tags', function (Blueprint $table) {        $table->increments('id');        $table->string('name');        $table->timestamps();    });}

    タグ モデルを生成した後、tag.php ファイルについて心配する必要はありません。これは、tag_id と のみを保存するリレーションシップ テーブルarticle_tag も必要であるためです。 Article_id なので、作成しましょう:

    php artisan make:model Tag

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

    php artisan make:migration create_article_tag_table --create=article_tag

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

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

    foreign(): 外部キー

    references(): 参照フィールド

    on(): 参照テーブル

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

    ここに削除が続きます、記事を削除する場合など、article_tag に同じarticle_id を含むレコードも削除します

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

    $table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');

    OK、これら 2 つのテーブルを生成したら、正式に作業を開始できます。

    Eloquent 関係を宣言する

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

    php artisan migrate

    Tag.php でも同じです:
    public function tags()    {        return $this->belongsToMany('App\Tag');    }

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

     public function articles()    {        return $this->belongsToMany('App\Article');    }

    OK , このようにして、多対多の関係が宣言されます。

    Select2 を使用します

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

    次に、ユーザー エクスペリエンスを向上させるために、多くのタグを備えた Select2 を紹介します。オプションを選択したときのパフォーマンスは非常に完璧でした。

    Select2の使い方: https://select2.github.io/examples.html

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

     public function articles()    {        return $this->belongsToMany('App\Article','conversation_id');    }

    93f0f5c25f18dab9d176bd4f6de5d30e55c25167d074fb13c2efd6c7049212b1「Multiple」を意味します。複数選択モードを有効にします。 $tags はデータベースのタグ テーブルから取得する必要があるデータなので、当然、ArticleController の create() メソッドに移動してコードを少し変更します。

    <div class="form-group">        {!! Form::label('tag_list','选择标签') !!}        {!! Form::select('tag_list[]',$tags,null,['class'=>'form-control js-example-basic-multiple','multiple'=>'multiple']) !!}</div>

    ここでは lists() メソッドを使用して追加します。タグ (タグ データ テーブルの場合) の名前と ID は Eluqoent 形式で返されます。dd($tags) を使用して確認できます。さて、この時点で作成ページを見てみましょう:

    この時点では、スタイルが 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>

    我们在c1a436a314ed609750bd7c7d319db4da标签下面增加一个ff6d136ddc5fdfeffaf53ff6ee95f185列表,然后是首先将发表日期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字段完美呈现。接下来我打算说一说怎么实现修改文章了,这是一个必走的流程嘛。所以。。。

    最后,Happy Hacking

    声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。