eloquent - Laravel 5: Chicken and egg when creating a one-to-one relationship -


let's assume have 2 model elements:

person computer 

in application person may have 1 computer (a person has 0..1 computers).

so

in user model, have:

 public function computer()  {      return $this->hasone('app\model\computer');  } 

in computer model have:

public function owner_user() {         return $this->belongsto('app\model\user'); } 

sometimes in application need create computer. computers cannot without owners, when information computer create, information owner.

what elegant way create both new objects (computer , person), associate them reference ids without doing multiple saves?

my problem is: ids being generated when eloquent model saved. because of that, have chicken , egg problem can't save computer, because don't know id of owner person, , can't save person because don't know id of owned computer.

i doing multiple saves , having stub id temporarily saved until other objects saved, , update id of first 1 saved.

there must more elegant way save 2 or more items @ same time, reference ids in place, single call - , without having worry database id integrity in high volume web server.

it seems associate function existing records. there no other way situation having save person + save computer + associate?

here's schema of people (users) , computers.

    users     +----------------+---------------------+------+-----+---------+----------------+     | field          | type                | null | key | default |          |     +----------------+---------------------+------+-----+---------+----------------+     | id             | bigint(20) unsigned | no   | pri | null    | auto_increment |     | username       | varchar(45)         | no   | uni | null    |                |     | email          | varchar(45)         | no   |     | null    |                |     | password       | text                | no   |     | null    |                |     | remember_token | varchar(100)        | no   |     | null    |                |     | created_at     | timestamp           | yes  | mul | null    |                |     | updated_at     | timestamp           | yes  | mul | null    |                |     +----------------+---------------------+------+-----+---------+----------------+       computers     +----------------------------+---------------------+------+-----+---------+----------------+     | field                      | type                | null | key | default |          |     +----------------------------+---------------------+------+-----+---------+----------------+     | id                         | bigint(20) unsigned | no   | pri | null    | auto_increment |     | user_id                    | bigint(20)          | no   | uni | null    |                |     | name                       | varchar(45)         | no   | mul | null    |                |     | created_at                 | timestamp           | yes  | mul | null    |                |         | updated_at                 | timestamp           | yes  | mul | null    |                |     +----------------------------+---------------------+------+-----+---------+----------------+ 

for least amount of database work, want create user first , create computer. way, can have 1 save user, , 1 save computer, 2 writes database.

if create computer first, have create computer, create user, , update computer user id, 3 writes database instead of two.

however, since you're creating 2 new records (user , computer), fact you're going have @ least 2 writes database, no matter do.

this you're looking at:

// create user object in database (first write) $user = \app\model\user::create([     'name' => $request->input('user_name'),     'password' => $request->input('user_password') ]);  // save on relationship update foreign key on // given model , save whole model database (second write). $user->computer()->save(new \app\model\computer([     'name' => $request->input('computer_name') ])); 

it sounds concern may have referential integrity. happens if user saves fine, there problem saving computer? want keep user, or should seem user save never happened?

if have multiple database writes should treated all-or-nothing situation, you'll need database transaction. if work done inside database transaction, can have database writes automatically rolled if 1 of them fails.

db::transaction(function() {     $user = \app\model\user::create([         'name' => $request->input('user_name'),         'password' => $request->input('user_password')     ]);     $user->computer()->save(new \app\model\computer([         'name' => $request->input('computer_name')     ])); }); 

with code, if save of computer throws exception, user created automatically undone. laravel's documentation on transactions here.

one thing note regarding transactions need make sure database you're using supports them. example, mysql, innodb , bdb storage engines support transactions. other storage engines (e.g. myisam) not. code not throw errors, database writes complete not rolled back.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -