codeigniter4 / CodeIgniter4

Open Source PHP Framework (originally from EllisLab)
https://codeigniter.com/
MIT License
5.3k stars 1.9k forks source link

Dev: Model needs new method - findOrCreate #5163

Open lonnieezell opened 2 years ago

lonnieezell commented 2 years ago

The Model should provide a new convenience method, findOrCreate that can be given a set of criteria to locate within the db table, or create a new record using that data and an additional set of data that was provided.

Must work with all currently supported databases.

Undecided which version would work fit the project best, so am open to discussion on this one:

$userModel->where('email', 'johnsmith@example.com')->findOrCreate(['key' => 'value', ...]);

// or

$userModel->findOrCreate(['existing_key' => 'value'], ['new_key' => 'value']);

References:

iRedds commented 2 years ago

Either your example is incorrect or the concept is lame. You are talking about implementing a method in a model, but the example shows working with the BaseBuilder class.

In the CI paradigm, the BaseBuilder class provides simple basic methods for base operations (write/read). The new method in this case looks like sugar for sequential operations (read/read + write + read), which is contrary to the paradigm.

Model and BaseBuilder do not have create method, but insert method. This means that the new method must be named findOrInsert.

The second version is more compact, but it seems to me that the first parameter should also accept a string so that you can specify a key from the second palarament.

$data = ['a' => 1, 'b' => 2];
->findOrCreate('a', $data); // IMHO it looks better than
->findOrCreate(['a' => $data['a']), $data); 
kenjis commented 2 years ago

CakePHP has findOrCreate(). https://book.cakephp.org/4/en/orm/saving-data.html#find-or-create-an-entity

lonnieezell commented 2 years ago

CakePHP has findOrCreate().

Laravel also has it. The difference with Cake's is that we can't always assume an entity is being used, but it's interesting to be able to use one. I don't think that's necessary for this first pass, though.

@iRedds you're right - the example code was wrong. I'll fix that. And I have no problem with it being called findOrInsert.

kenjis commented 2 years ago

@lonnieezell Do you mean firstOrCreate in Laravel? https://laravel.com/docs/8.x/eloquent#retrieving-or-creating-models

Valkhan commented 1 year ago

Isn't that what save() does?

https://codeigniter4.github.io/CodeIgniter4/models/model.html?highlight=save#save

kenjis commented 1 year ago

No. save() is to create or update.

datamweb commented 1 year ago

This feature is needed, I recently noticed its absence.

For example, the user may want to log in with Google, so the system first checks whether the user exists or not, and if there is, it is logged in.

If it does not exist, the new user is first registered and then logged in.

If this issue refers to this issue, I agree to add it.

kenjis commented 6 months ago

This method seems to be extremely complex. Do we really need this? See https://zenn-dev.translate.goog/mpyw/articles/laravel-v10-create-or-first?_x_tr_sl=ja&_x_tr_tl=en&_x_tr_hl=ja&_x_tr_pto=wapp&_x_tr_hist=true

lonnieezell commented 6 months ago

Actually, that article reinforces the idea that we should provide a solution. This is a fairly common pattern developers have to do. I'll admit I never coded for race conditions in those situations. I'm sure most people don't.

kenjis commented 6 months ago

Okay.

References: