1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

laravelで自分のサイトを作るときにつまずいたところ:その1

Last updated at Posted at 2021-04-23

##今回は
今回は自分のサイトを追加するものを作っているのですが、HTMLや、Laravelなどサイトにタグをつけることができればいいなと思い、色々と調べながら作りました。その際につまずいたところをまとめて書き留めておきたいと思います。(9割自分のため)

##多対多を作るとき
中間テーブルが必要になり、3つのテーブルをつなぎ合わせる必要があります。やっていきましょう。

SitesController.php
    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

中身を編集します。

create_site_tag_table.php
    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[]と配列で渡せるように語尾に[]がついています。

index.blade.php
    <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{}をあらかじめ作ってくれます。便利。

##以上。
非常に参考にしたサイト

このような感じで少しずつではありますが、自分の作りたいサイトを作れるようになって行っています。
またつまずいたら書き留めていつか完成する日が来ることを楽しみにしています。

今はセレクトボックスを使った昇順降順ソートでつまづいています。これは質問で書いてみようかな。
ではまた。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?