質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.92%

複数テーブルへデータ挿入時にGeneral error: 1364 Field 'name' doesn't have a default valueというエラーに悩まされています。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 233

m.kk

score 7

Laravel Framework 7.19.1 を使っております。

やりたいこと
データ登録時に同時に他テーブルにも同時に登録したい。

具体的にいうと
bookデータ登録時に一緒にtagデータも挿入したい。
下記にコードを貼らせていただきます。

BookController

public function store(Request $request, Book $book, Tag $tag)
    {
        // dd($request->all());
        $user = auth()->user();
        $file_name = $request->file('book_image')->getClientOriginalName();
        $request->file('book_image')->storeAs('public',$file_name);

        $data = $request->all();
        $validator = Validator::make($data,[
            'title' => ['string', 'max:30'],
            'over_view' => ['string', 'max:20480'],
            'book_image' => ['file', 'image', 'mimes:jpeg,png,jpg', 'max:20480']
        ]);
        $validator->validate();


        $book = new Book;
        $book->bookStore($user->id, $data);
        $book->save();
        // dd($book);

        $data = [];
        if(isset($data["tags"])) {
            $tag->tagStore($data["tags"]);
            $tag_ids = $tag->getTagIds($data["tags"]);
            $book->bookTagSync($tag_ids);
        }
        $tag->save();
        return redirect('/books')->with('success', '投稿が完了しました。');

    }
BookModels

 public function tags()
    {

        return $this->belongsToMany(Tag::class);
    }

    public function bookStore(Int $user_id, Array $data)
    {
      //本登録項目をmodelにまとめcontrollerの記述を少なく
      $this->user_id = $user_id;
      $this->book_image = $data['book_image'];
      $this->title = $data['title'];
      $this->over_view = $data['over_view'];
    //   $this->status = $data['book_status_id'];
      $this->save();
      return;
    }

    public function getEditBook(Int $user_id, Int $id)
    {
      return $this->where('user_id', $user_id)->where('id', $id)->first();
    }

    public function bookUpdate(Int $book_id, Array $data)
    {
      $this->id = $book_id;
      $this->title = $data['title'];
      $this->over_view = $data['over_view'];
    //   $this->status = $data['book_status_id'];
      $this->update();
      return;
    }

    public function bookDestroy(Int $user_id, Int $book_id)
    {
        return $this->where('user_id',$user_id)->where('id',$book_id)->delete();
    }


    //タグ
    public function bookTagStore(Array $tag_ids){
        foreach($tag_ids as $tag_id) {
          $this->tags()->attach($tag_id);
        }
      }

      public function bookTagSync(Array $tag_ids){
        //同期
          $this->tags()->sync($tag_ids);
      }
tagModels

class Tag extends Model
{
    public $timestamps = false;

    public function books()
    {
        return $this->belongsToMany(Book::class, 'book_tag', 'tag_id', 'book_id');
    }


    public function tagStore(Array $_tag_names){
        //タグがすでにあるかの判定
        $this->name = $_tag_names['name'];
        if(!empty($_tag_names)){
            //タグがあるかforeachで探す.['name' => $tag_name]
            foreach($_tag_names as $tag_name){
                $tag_names[] = ['name' => $tag_name];
            }
            //insertOrIgnoreであれば無視、なければ挿入
            DB::table('tags')
            ->where('name','')
            ->insertOrIgnore($tag_names);
        }
      }

    public function getTagIds($tag_names){
    foreach($tag_names as $tag_name){
        //idから名前を1から取り出して$tag_idに代入
        $tag_id = $this::select('id')->where("name",$tag_name)->first();
        //$tag_ids[]を作成してidを全て代入
        $tag_ids[] = $tag_id->id;
    }
    return $tag_ids;
    }


    public function getPopularTags(){
        //withCountでレコード数をとる
        //0で公開しているbooksのデータを呼び出し
        $popular_tags = $this::withCount([ 'books' => function($query) {
            $query->where('status',0);
        }])
        ->orderBy('books_count', 'desc')
        ->take(5)
        ->get();
        return $popular_tags;
    }

}
view

@extends('layouts.app')
@section('content')
<form action="{{ route('books.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<input type="text" name="title" placeholder="タイトル" class="form-control form-control-lg">
<textarea  rows="8" cols="40" type="textarea" name="over_view" placeholder="概要" class="form-control form-control-lg"></textarea>
<input type="file" id="book_image" name="book_image" >
<div class="p-postEdit-form__input-tags">
    @for ($i = 1; $i <= 5; $i++)
       <input type="text" name="tags[]" class="p-postEdit-form__input-tag @error('tags[]'.$i) is-error @enderror" value="{{ old('tags[]'.$i) }}" placeholder="#タグ">
        @error('tags[]'.$i)
           <span class="p-postEdit-form__errorMsg" role="alert">
              <strong>{{ $message }}</strong>
              </span>
        @enderror
     @endfor
     </div>
<input type="submit"  value="Submit"></button>
</form>
@endsection
DB

class CreateBooksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('books', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user_id')->comment('ユーザーID');
            $table->string('book_image')->comment('画像');
            $table->string('title');
            $table->text('over_view')->comment('概要');
            $table->unsignedSmallInteger('status')->default(0)->comment('0:公開,1:非公開');
            $table->timestamps();
            $table->foreign('user_id')
              ->references('id')
              ->on('users')
              ->onDelete('cascade')
              ->onUpdate('cascade');
        });
    }


class CreateTagsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tags', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name')->unique()->comment('カテゴリー名');
        });
    }


   class CreateBookTagTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('book_tag', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedInteger('book_id')->comment('本ID');
            $table->unsignedInteger('tag_id')->comment('カテゴリーID');

            $table->foreign('book_id')->references('id')->on('books')->onDelete('cascade');
            $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');

            $table->unique([
                'book_id',
                'tag_id'
            ]);
        });
    }

中間テーブルも指定して
->insertOrIgnore($tag_names);でカラムは指定しているので入ると思っているのですが、うまくいかなく質問させていただきます。
どうぞよろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

できました!
コントローラの順番がおかしかったです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • PHPに関する質問
  • 複数テーブルへデータ挿入時にGeneral error: 1364 Field 'name' doesn't have a default valueというエラーに悩まされています。