Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Eloquent - firstOrCreate() on a relationship

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.

like image 804
Kousha Avatar asked May 31 '14 01:05

Kousha


4 Answers

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.

like image 34
delatbabel Avatar answered Oct 06 '22 00:10

delatbabel


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.

like image 52
agm1984 Avatar answered Oct 05 '22 22:10

agm1984


This should do:

Client::find($id)->first()->users()->firstOrCreate(array('email' => $email));
like image 22
Julio Popócatl Avatar answered Oct 05 '22 23:10

Julio Popócatl


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;
}
like image 35
anil pahelajani Avatar answered Oct 06 '22 00:10

anil pahelajani