10
votes

When I try the firstOrCreate() on a relationship of another model, it does not work:

Client::find($id)->users()->firstOrCreate(array('email' => $email));

This returns an error saying

Call to undefined method Illuminate\Database\Query\Builder::firstOrCreate()

Running this directly on the model User will work though.

4
This won't work, you have to do it manually/directly using User model because users() should return a collection object when get() gets called and in this case it'll return a Builfer instance.The Alpha
I tested this with my own models and this works - how had you defined your relation? Do you use any of the belongsTo, hasOne, hasMany relations or did you defined your own using the DB class or anything like this? Or is it possible that you haven't any Client with the given id?Gummibeer
It's also documented laravel.com/docs/5.1/… if you use the laravel relations than it should work. If you do and it doesn't work than we need a bit more code.Gummibeer

4 Answers

8
votes

This won't work, you have to do it manually/directly using User model because users() should return a collection object

This is correct, the users() function does not return a (new, empty or created) User model, it returns a collection object.

It's also documented http://laravel.com/docs/5.1/eloquent-relationships#inserting-related-models if you use the laravel relations than it should work.

You are misinterpreting that document. The relationship object has a create() method and a save() method, however the relationship object is not a full model object. To get all of the functionality of a full User model object (such as firstOrCreate()) then you have to call them on the model object.

So, for example, this code should work:

$user = User::firstOrNew(array('email' => $email));
Client::find($id)->users()->save($user);

Note that it should be OK to save the $user object here directly from the Client model's relationship, even though it may already exist here, it should just update the client_id field on the $user object when you do so.

1
votes

This should do:

Client::find($id)->first()->users()->firstOrCreate(array('email' => $email));
1
votes

The firstOrCreate method will attempt to locate a database record using the given column / value pairs. If the model can not be found in the database

public function firstOrCreate() {
    $requestData = [
        'name' => 'Salma Klocko',
        'email' => '[email protected]'
    ];
    $customer = Customer::firstOrCreate($requestData);
    echo "Insert customer detail Successfully with ID : " . $customer->id;
}
0
votes

You can use updateOrCreate:

$user = App\User::query()->firstWhere('email', '[email protected]');

$user->sandwiches()->updateOrCreate(['user_id' => $user->id], [
    'cabbage' => false,
    'bacon' => 9001,
]);

updateOrCreate has two parameters. The first one is the match condition(s). The second one is the upsert data. For example, if there is no row with user_id === $user->id, a record will be created with that and the fields from the second parameter.