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

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

ただいまの
回答率

89.21%

LaravelでSQLSTATE[42S22]がでる

解決済

回答 1

投稿 編集

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

yor13

score 8

環境

Laravel 5.8
Windows
MySQL

エラー内容

Illuminate \ Database \ QueryException (42S22)
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user_id' in 'field list' (SQL: insert into players (namemoneyuser_idupdated_atcreated_at) values (test, 10000, 1, 2020-03-16 19:14:41, 2020-03-16 19:14:41))
Previous exceptions
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user_id' in 'field list' (42S22)

試したこと

データベースを新規作成
テーブルを新規作成
プロジェクトを新規作成
キャッシュクリア

個人的見解

一番最初、aプロジェクトで上記のエラーが出ました。
aプロジェクトではuser_idカラムを使っていました。ネットを見るとMySQLの問題であることがわかりuser_idカラムがないテーブルの新規作成などをしましたが問題解決はしませんでした。どこかにキャッシュが残っているのかと思い、キャッシュクリアをしてもダメでした。

そこでcプロジェクトを新規作成して、同時に新しいデータベース、ユーザー、テーブルを作りました。もちろんenvファイルは新しいDB、ユーザーに対応するように編集しました。ですが、また上記のエラーが出ました。

個人的意見としては、ソースコードの問題ではなく、MySQLの問題だと思っています。
下記に、一応ソースコードを載せておきます。

コード

//D:\c\database\migrations\2020_03_16_190902_create_players_table.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePlayersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('players', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->integer('money');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('players');
    }
}
//D:\c\app\Player.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Player extends Model
{
    protected $fillable = [
        'name', 'money',
    ];
}
//D:\c\app\User.php
<?php
namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function player(){
        return $this->hasOne('App\Player');
    }
}
//D:\c\app\Http\Controllers\Auth\RegisterController.php
<?php

namespace App\Http\Controllers\Auth;

use App\User;
use App\Player;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;

class RegisterController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

    use RegistersUsers;

    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return \App\User
     */
    protected function create(array $data)
    {
        $user = User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
        $user->player()->create([
            'name' => $data['name'],
            'money' => 10000,
        ]);
        return $user;
    }
}
playersテーブル
+------------+---------------------+------+-----+---------+----------------+
| Field      | Type                | Null | Key | Default | Extra          |
+------------+---------------------+------+-----+---------+----------------+
| id         | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(255)        | NO   |     | NULL    |                |
| money      | int(11)             | NO   |     | NULL    |                |
| created_at | timestamp           | YES  |     | NULL    |                |
| updated_at | timestamp           | YES  |     | NULL    |                |
+------------+---------------------+------+-----+---------+----------------+
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2020/03/17 05:25

    では、playersテーブルのidカラムをあえてuser_idという名前にするとどうですか?

    キャンセル

  • yor13

    2020/03/17 05:32

    エラーが出ませんでした
    問題なくplayersテーブルにデータが入りました

    キャンセル

  • m.ts10806

    2020/03/17 05:33

    了解です。ただ、それがやりたいことではないと思うので、回答しました。

    キャンセル

回答 1

checkベストアンサー

+1

「おそらく」ですが、分かりました。

Userモデルに下記の記述があります。

public function player(){
return $this->hasOne('App\Player');
}

1対1でリレーションが貼られてます。
ということはPlayerテーブルにもリレーションの向き先である「user_id」が必要です。

Eloquentはリレーションの外部キーがモデル名に基づいていると仮定します。この場合自動的にPhoneモデルはuser_id外部キーを持っていると仮定します。この規約をオーバーライドしたければ、hasOneメソッドの第2引数を指定してください。

MySQL側の問題かどうかというと微妙なところですが、そもそものDB設計が間違っているということになりますね(Laravelの思想に沿ってない)。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/03/17 06:07

    設計次第ですけど、idカラムはあくまでplayerテーブルのidであって、userテーブルのリレーションになってはよろしくないと思います。
    例えuserテーブルにデータ追加時にplayerテーブルが追加され、1対1で更新されるとしても、別カラムで管理すべきかと思います。
    「エラーが出ない手法」より「設計」で考えてください。playerテーブルがどのようなタイミングで追加され、更新されるのか。

    キャンセル

  • 2020/03/17 06:13

    リレーションの理解が深まりました。
    わざわざ回答していただきありがとうございました。
    ベストアンサーにさせていただきます。

    キャンセル

  • 2020/03/17 06:18

    解決されたようで何よりです。

    キャンセル

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

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