LoginSignup
1
0

More than 1 year has passed since last update.

Laravelで作られた掲示板に機能を追加する①

Last updated at Posted at 2021-09-17

Laravelの勉強の備忘録です

Laravelの勉強のためにこのサイト【Laravel】掲示板を作成する(1)~(7)をなぞりながら掲示板を作りました。
記事を書かれた方にこの場を借りてお礼申し上げます。

そしてLaravel技術力アップのため、この掲示板に機能を追加していきます(本記事の内容)

環境

前提条件:【Laravel】掲示板を作成する(1)~(7)をLaravel 8で作り終えていること。

Windows 10
Laravel 8(※掲示板を作成された方の環境はLaravel 5.8のようですが、8で作っています)
Docker


目標

  • Userデータを作成し、UserとPostやCommentのリレーションを設定する
    • Fakerを使いUserのダミーデータを作成
    • PostとCommentテーブルのnameカラム名削除をし、user_idカラムを作成
    • Userとのリレーションの設定を行う
    • viewの変更
    • 検索の修正


Fakerを使いUserのダミーデータを作成

Userのダミーデータを作成します。
UserモデルとUserFactoryは仕様で作成されているので、Seederを作成します。

$ php artisan make:seeder UsersTableSeeder

ダミーデータをとりあえず5つ作成

database\seeds\UsersTableSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\User;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        User::factory(5)->create();
    }
}

パスワードの記述の変更

database\factories\UserFactory.php
    public function definition()
    {
        return [
            'name' => $this->faker->name(),
            'email' => $this->faker->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'remember_token' => Str::random(10),
        ];
    }

  ↓ 変更 ↓ 

    public function definition()
    {
        return [
            'name' => $this->faker->name(),
            'email' => $this->faker->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => bcrypt('password'),
            'remember_token' => Str::random(10),
        ];
    }

ダミーユーザーを5つ作ったので、PostsとCommentsテーブルのuser_id(後ほど作成)に1~5の数字をランダムに流し込むために内容を変更します。

database\factories\PostFactory.php と database\factories\CommentFactory.php(2つとも記述方法が同じ)
    public function definition()
    {
        return [
       (略)
            // 'name' => $this->faker->name,    // 氏名
             ↓↓ 変更
            'user_id' => $this->faker->numberBetween(1,5),
       (略)
        ];
    }

seederを流し込むための記述を追記します。

database\seeders\DatabaseSeeder.php
    public function run()
    {
        $this->call(UsersTableSeeder::class); // ← リレーションの関係でPostsTableSeederより上に追記
        $this->call(PostsTableSeeder::class);
    }


PostとCommentテーブルの内容を変更

nameカラムを削除し、user_idを追加します。

Laravelはデフォルトではカラム名の変更はできないらしいので、Doctrine DBALをインストールします。
(カラム名を変更していないので、Doctrine DBALはインストールしなくてもいいかもしれません)

$ composer require doctrine/dbal

postsとcommentsテーブルのnameカラムを削除し、user_idカラムを作成するためのマイグレーションファイルの作成を行います。

(1)nameカラム削除用のmigrationファイルの作成
とりあえずわかりやすいかなと思う名前で作成。

$ php artisan make:migration drop_name_column_from_posts_table --table=posts
$ php artisan make:migration drop_name_column_from_comments_table --table=comments

最初はdrop_column_name_columnにしようとしました。
しかし、posts作成後にcomments分を作成しようとしたところ、既にファイルが存在しているとエラーがでたため、上記のような書き方にしました。

(2)nameカラム削除用のmigrationファイルへの記述

drop_name_column_from_posts_table.phpとdrop_name_column_from_comments_table.php(2つとも記述方法が同じ)
    public function up()
    {
        Schema::table('comments', function (Blueprint $table) {
            $table->dropColumn('name');  //カラムの削除
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('comments', function (Blueprint $table) {
            $table->string('name');  //カラム追加
        });
    }

(3)nameカラム削除用のmigrationファイルの反映

$ php artisan migrate

down処理の検証をしたい場合は、 php artisan migrate:rollback --step=2 とやって、カラムが巻き戻っているかを確認すればいいと思います。というか、した方がいいです。

(4)user_idカラム追加用のmigrationファイルの作成

$ php artisan make:migration add_user_id_to_posts_table --table=posts
$ php artisan make:migration add_user_id_to_comments_table --table=comments

(5)user_idカラム追加用のmigrationファイルへの記述

Usersテーブルのidを確認したところ、タイプがbigint、属性がunsignedだったのでunsignedBingIntegerで作成します。

add_user_id_to_posts_table.php
    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->unsignedBigInteger('user_id');  //カラム追加
            $table->foreign('user_id')->references('id')->on('users');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->dropForeign('posts_user_id_foreign');
            $table->dropColumn('user_id');
        });
    }
add_user_id_to_comments_table.php
    public function up()
    {
        Schema::table('comments', function (Blueprint $table) {
            $table->unsignedBigInteger('user_id');  //カラム追加
            $table->foreign('user_id')->references('id')->on('users');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('comments', function (Blueprint $table) {
            $table->dropForeign('comments_user_id_foreign');
            $table->dropColumn('user_id');
        });
    }

リレーション設定のために内容に変更や追記をします。

app\Models\User.php
    public function posts()
    {
        return $this->hasMany('App\Models\Post');
    }

    public function comments()
    {
        return $this->hasMany('App\Models\Comment');
    }
app\Models\Comment.php

    protected $fillable = [
        'post_id',
        'user_id', // 'name'から変更
        'comment', 
    ];

    public function user() // 追記
    {
        return $this->belongsTo('App\Models\User');
    }
app\Models\Post.php

    protected $fillable = [
        'user_id', // 'name'から変更
        'subject',
        'message', 
        'category_id'
    ];

    public function user() // 追記
    {
        return $this->belongsTo('App\Models\User');
    }

これでseederとリレーションが出来たので、ダミーデータを流し込みます。

$ php artisan migrate:refresh --seed


viewの編集

今まではpostsテーブルのnameカラムを参照していました。
しかし、nameカラムを削除し、user_idを参照するようになったので、内容を変更します。

index.blade.php
                <td>{{ $post->name }}</td>
         ↓ 変更 ↓
                <td>{{ $post->user->name }}</td>

edit.blade.php
                        value="{{ old('name') ?: $post->name }}"
             ↓ 変更 ↓
                        value="{{ old('name') ?: $post->user->name }}"

上記の記述にするとちゃんと名前が表示されるようになりました。


検索の修正

テーブルの構造を変えたので、検索をしても名前がひっかからなくなりました。
ですので、検索対象のカラムを変更します。

postsテーブルのmessegeカラム
postsテーブルのnameカラム

postsテーブルのmessegeカラム
usersテーブルのnameカラム

app\Models\Post.php

    public function scopeFuzzyNameMessage($query, $searchword)
    {
   (
        return $query->where(function ($query) use($searchword) {
            $query->orWhere('name', 'like', "%{$searchword}%")
                ->orWhere('message', 'like', "%{$searchword}%");
        });
    }

  ↓ 変更 ↓

    public function scopeFuzzyNameMessage($query, $searchword)
    {
   (
        $user_ids = User::where('name', 'like', "%{$searchword}%")->pluck("id");
        $query->whereIn('user_id', $user_ids)
              ->orWhere('message', 'like', "%{$searchword}%");
        return $query;
    }

まずuser_idsに検索ワードと一致したusersテーブルのnameカラムと一致するidをぶち込みます。
whereInを使っている理由は、user_idsはpluckメソッドを使っていて配列が入っています。そのためwhereIn()を使うのが適しているらしいからです。

この修正を行った後に検索をすると、名前とメッセージに一致している記事を拾ってきてくれるようになります。



続きは、Laravelで作られた掲示板に機能を追加する②にて!

1
0
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
0