##今回は
今回は自分のサイトを追加するものを作っているのですが、HTML
や、Laravel
などサイトにタグをつけることができればいいなと思い、色々と調べながら作りました。その際につまずいたところをまとめて書き留めておきたいと思います。(9割自分のため)
##多対多を作るとき
中間テーブルが必要になり、3つのテーブルをつなぎ合わせる必要があります。やっていきましょう。
public function tags()
{
return $this->belongsToMany('App\Models\Tag')->withTimestamps();
}
belongsToMany('modelのpath')
をかき、->withTimestamps()
で中間テーブルの created_at 、 updated_at タイムスタンプを自動的に保守します。
中間テーブルを作成します。
php artisan make:migration create_site_tag_table
中身を編集します。
public function up()
{
Schema::create('site_tag', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('site_id');
$table->unsignedBigInteger('tag_id');
$table->foreign('site_id')->references('id')->on('sites')->onDelete('cascade');
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
$table->timestamps();
});
}
中間テーブルの名前には決まりがあって二つの単語をアンダーバー「_」で繋げます。そして順番にも決まりがあり、アルファベット順の先からつけることになっています。site_tag
のように「t」より「s」方がアルファベット順でいくと先に来るので「site_tag」になります。
あとは、foreign~~の行で「site_id」とsitesテーブルのidが紐づけられてるよと書いてあげます。
そのあと、作りたいところに$site = new Site();
と入れて値を代入していき、
$site->tags()->attach(request()->tags);
と書いてあげます。
attach()
は中間テーブルに値を入れてくれます。
request()
は$request
と同じ意味です。$request
と書き換えてもできます。
request()->後のtagsはcheckboxのname属性です。tags[]
と配列で渡せるように語尾に[]がついています。
<p>
@foreach($tags as $tag)
<label>
<input type="checkbox" name="tags[]" value="{{ $tag->id }}">{{ $tag->name }}
</label>
@endforeach
</p>
このような感じです。
この後に大きな落とし穴にはまったのですが、
$site->save();
の前にattach()の文を書いてしまうと、エラーが出てしまいます。
site_id is null.
と言われます。めちゃくちゃはまっていたのですが、答えは簡単でした。save()
してからid
がふられるのでsave()
の前にattach()
をしてしまうと、"idがないよ!"と言われてしまうわけですね。
なんという初歩的なミス...。精進します...。
ここさえミスらなければ多対多の中間テーブルをつかったシステムはうまくいくと思います。
他につまずくところがあればコメントください!
##aタグの中のaタグ
aタグの中にaタグを入れるとバグります。なんでかわかんないけどバグります。
aタグの中にはaタグを入れちゃダメ。詳しくいうとaタグが勝手に閉じてしまいます。
後々直って欲しいですね。
##compactとwithは一緒
public function test() {
$test_1 = "test";
return view('tests.index',compact('test_1'));
}
これと、
public function test() {
$test_1 = "test";
return view('tests.index')->with('test_1',$test_1);
}
これは同じ意味を示す。
##データベースに元から値を入れるときは
タグをつけてソートできるようにしたいとなった時に、サイト追加画面でタグをチェックボックスで表示し、チェックしたタグをつけることができるようにしようと思いました。その時に、タグの初期値を作りたいと思いました。シーダーファイルをいじることでできるらしい。
php artisan make:seeder TagsTableSeeder
シーダーファイルはdatabase>seedersの中に作られます。
TagsTableSeederをこのようにいじります。
$Tag_Array = ["#HTML", "#CSS", "#JavaScript", "#PHP", "#Ruby", "#Laravel", "#MySQL", "#Docker"];
for($i = 0; $i < count($Tag_Array); $i++)
{
$tag = new Tag();
$tag->name = $Tag_Array[$i];
$tag->save();
}
こうすることによって、Tag_Arrayに入っている値がデータベースに入ります。
docker-compose exec workspace bash //laravel内に入ります。
php artisan db:seed --class=TagsTableSeeder
これで完了です!
これでtag_tableの初期値をつけることができました。
##::resource
php artisan make:controller PostsController --resource
--resource
をつけると、controller内にindex{}や、show{}、create{}をあらかじめ作ってくれます。便利。
##以上。
非常に参考にしたサイト
このような感じで少しずつではありますが、自分の作りたいサイトを作れるようになって行っています。
またつまずいたら書き留めていつか完成する日が来ることを楽しみにしています。
今はセレクトボックスを使った昇順降順ソートでつまづいています。これは質問で書いてみようかな。
ではまた。