4
votes

A user hasOne car.

users

id | name
1  | Bob
2  | Alice

cars

idMember |  color  |  energy
   1     |  blue   |    0.95

Inside the User class I have

public function car()
{
  return $this->hasOne('App\Car','idMember');
}

I want to call updateOrCreate on the relation Model like this:

$user->car()->updateOrCreate(['idMember' => $user->id], ['color' => 'red', 'energy' => '0.1']); 

However, I get the error message

"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'id' in 'where clause' (SQL: update cars set color = red, energy = 0.1, updated_at = 2018-01-12 15:26:47 where id is null)

Why is he looking for

id is null

?

4
Laravel expect each entity to have an auto-incrementing primary key with the name id , having a primary key is also a relational requirement (though it may be a composite key which laravel does not support). Just save your sanity and add an auto incrementing id column in that table so everything has a unique id. Also by convention laravel expects the foreign key to be <singular other table>_id i.e. in your case idMember should be user_id (but you can change that in your hasOne parameters)apokryfos
@apokryfos oh yeah your right.. forgot about that. But I rather change the primaryKeyof my car model since no AI key is needed in a hasOne relation.Adam
On one to one relationships having the foreign key as the primary key as you have done is also an option.apokryfos

4 Answers

8
votes

To be clear, your original syntax is correct. You can use it on a relation:

$user->car()->updateOrCreate(['idMember' => $user->id], [
    'color' => 'red',
    'energy' => '0.1',
]);

This will check if there is a car with idMember === $user->id; if so, update color and energy. If not, it will create a car record with idMember, color, and energy.

I haven't tested, but based on the first parameter's array type, you should be able to pass in multiple match conditions, such as

['idMember' => $user->id, 'day' => 'tuesday']
2
votes

Your cars model should have a primary key, commonly called "id". Create it.

1
votes

This is how I solved my problem without adding an unnecessary auto incrementing id to the cars model:

class Car extends Model
{

  protected $primaryKey   = 'idMember';
  public    $incrementing = false;
-2
votes

In your model mention the primaryKey if primarykey is not "ID"

protected $primaryKey = "Your Primary Key";

If you do not need icnrementing for your primary key

public    $incrementing = false;

Thats it ..