Save relationship 1: 1 in Laravel 5.3

4

In my scenario, I have the tables of users and teachers, where a teacher has a user, so I have a 1:1 relation.

Migrations:

create_users_table

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name', 150);
    $table->string('username', 20)->unique();
    $table->string('email', 100)->unique();
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
});

create_teachers_table

Schema::create('teachers', function (Blueprint $table) {
    $table->increments('id');
    $table->date('birth');
    $table->string('about');
    $table->integer('user')->unsigned();
    $table->foreign('user')->references('id')->on('users');
    $table->timestamps();
});

Models:

User

protected $fillable = [
    'username', 'email', 'password', 'name', 'remember_token',
];


protected $hidden = [
    'password', 'remember_token'
];


public function teacher() {
    return $this->belongsTo(Teacher::class, 'teacher');
}

Teacher

protected $fillable = [
    'user', 'birth', 'about',
];

public function user()
{
    return $this->hasOne(User::class, 'user');
}

Controller Where do I try to create a teacher:

$f_teacher = $request->only('birth', 'about');
$f_user = $request->except('birth', 'about', '_token');

$teacher = new Teacher($f_teacher);
$teacher->user()->save( new User($f_user) );
$teacher->save();

When you run this page, the following error appears:

  

QueryException in Connection.php line 770: SQLSTATE [42S22]: Column not   found: 1054 Unknown column 'user' in 'field list' (SQL:

     

insert into users (name, email, username, password, user, updated_at, created_at) values (Nome do professor, [email protected], user-prof, senha-criptografada, ,2017-01-07 00:26:44, 2017-01-07 00:26:44) )

I know the error is because Laravel is reversing the relation, it is interpreting that the users table has the FK user and the% does not have, I tried to invert by putting HasOne in the user model and BelongsTo in the teacher model, but as expected did not work. Why is this relationship being reversed? How to solve?

    
asked by anonymous 07.01.2017 / 01:33

1 answer

2

Relationship 1: 1 Laravel

Following the documentation and comments, models and migrations need to be changed to fit in the 1: 1 relationship proposed by

  

Relação

  

Migrations

User

<?phpuseIlluminate\Support\Facades\Schema;useIlluminate\Database\Schema\Blueprint;useIlluminate\Database\Migrations\Migration;classUsersextendsMigration{publicfunctionup(){Schema::create('users',function(Blueprint$table){$table->increments('id');$table->string('name',150);$table->string('username',20)->unique();$table->string('email',100)->unique();$table->string('password');$table->rememberToken();$table->timestamps();});}publicfunctiondown(){Schema::drop('users');}}

Teachers

<?phpuseIlluminate\Support\Facades\Schema;useIlluminate\Database\Schema\Blueprint;useIlluminate\Database\Migrations\Migration;classTeacherextendsMigration{publicfunctionup(){Schema::create('teachers',function(Blueprint$table){$table->integer('userid')->unsigned();$table->primary('userid');$table->date('birth');$table->string('about');$table->foreign('userid')->references('id')->on('users');$table->timestamps();});}publicfunctiondown(){Schema::drop('teachers');}}

ThebigchangeinmigrationisinTeacher,andtherelationshipkeycannotbeauto-incrementbecauseitreceivesthekeyvalueoftherelationwithUserandistheprimarykeyoftheteacherstable.Summarizingthetable/fieldusers.idisrelatedtoteachers.userid,thusgeneratinga1:1relationship.

  

Models

User

<?phpnamespaceApp\Models;useIlluminate\Notifications\Notifiable;useIlluminate\Foundation\Auth\UserasAuthenticatable;classUserextendsAuthenticatable{useNotifiable;//configuraçõesaseremobservadasprotected$primaryKey="id";
    protected $table = "users";
    public $incrementing = true;

    protected $fillable = [
        'username', 'email', 'password', 'name', 'remember_token',
    ];

    protected $hidden = ['password', 'remember_token'];
    public function teacher()
    {
        return $this->hasOne(Teacher::class, 'userid','id');
    }
}

Teacher

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Teacher extends Model
{
    //configurações a serem observadas
    protected $primaryKey = "userid";
    protected $table = "teachers";
    public $incrementing = false;

    protected $fillable = ['userid', 'birth', 'about'];

    public function user()
    {
        return $this->belongsTo(User::class, 'userid', 'id');
    }
}

As already mentioned, the change is also in the model Teacher , where it should be indicated:

  • Primary key
  • Disable the auto-increment of this field which defaults to true;

and is in the model in that part:

//configurações a serem observadas
protected $primaryKey = "userid"; //setando a chave primária
protected $table = "teachers"; //nome da tabela na base de dados
public $incrementing = false; //desabilitando auto-incremento

In other words, it is the model User that generates the relationship between the tables and the key is Teacher . User has hasOne with Teacher , while Teacher has belongsTo with User .

Create a record:

//primeiro cria user
$data0['name'] = 'Usuario 1';
$data0['username'] = 'usuario1';
$data0['email'] = '[email protected]';
$data0['password'] = bcrypt('usuario1');
$user = new App\Models\User($data0);
$user->save(); // salva

//depois cria teacher para esse user.
$data1['birth'] = date('Y-m-d');
$data1['about'] = 'Sobre usuario1';
$user->teacher()->create($data1);

//exibindo informações.
var_dump($user->with('teacher')->where('id', $user->id)->first());

Looking for registration:

>>> $c->with('teacher')->find(6);
=> App\Models\User {#731
     id: 6,
     name: "Usuario 1",
     username: "usuario1",
     email: "[email protected]",
     created_at: "2017-01-07 12:23:39",
     updated_at: "2017-01-07 12:23:39",
     teacher: App\Models\Teacher {#738
       userid: 6,
       birth: "2017-01-07",
       about: "Sobre usuario1",
       created_at: "2017-01-07 12:23:39",
       updated_at: "2017-01-07 12:23:39",
     },
   }
>>>

Deleting this record and relation:

>>> $d = $c->find(6); //busca
=> App\Models\User {#711
     id: 6,
     name: "Usuario 1",
     username: "usuario1",
     email: "[email protected]",
     created_at: "2017-01-07 12:23:39",
     updated_at: "2017-01-07 12:23:39",
   }
>>> $d->teacher()->delete(); //excluindo teacher
=> 1
>>> $d->delete(); //excluindo user
=> true
>>>

References

07.01.2017 / 13:41