How to prevent duplicates in Laravel Eloquent? - laravel

I want to transform my database entry creation inside NewsletterController.php:
$email = $request->input('email');
$table = DB::table('newsletters');
$table->insert(array('email' => $email, 'created_at' => now()));
to prevent duplicate entries. I tried doing this:
$table = DB::updateOrCreate('newsletters');
but this method does not seem to exist for DB. How would I do that?

when you may want to update an existing record in the database or create it if no matching record exists. In this scenario, the updateOrInsert method may be used. The updateOrInsert method accepts two arguments: an array of conditions by which to find the record, and an array of column and value pairs indicating the columns to be updated.
The updateOrInsert method will attempt to locate a matching database record using the first argument's column and value pairs. If the record exists, it will be updated with the values in the second argument. If the record can not be found, a new record will be inserted with the merged attributes of both arguments
DB::updateOrInsert(['email'=>$eamil],['created_at'=>Carbon::now()]);
now, if email exists, the 'created_at' will be updated, otherwise a new row will be inserted with values of the merged array arguments

updateOrCreate you use for Eloquent Builder and updateOrInsert you use for Query Builder. Try with updateOrInsert.
$table = DB::updateOrInsert->table('newsletters')->([ 'id' => $request->id ], [
'email' => $email,
]);

Thanks to Moussab Kbeisy's comment I can validate for uniqueness which will return a 422 error if not met instead of inserting into the database:
$this->validate($request, [
'email' => 'required | unique:newsletters'
]);
$email = $request->input('email');
$table = DB::table('newsletters');
$table->insert(['email' => $email, 'created_at' => now()]);

Related

Laravel create command wont insert a value in database

Hello i am new to Laravel so currently im doing a CRUD. I have created this insert function that works well except one value is never inserted. This is the code below:
public function storeClient(Request $request) {
$request->validate([
'name' => 'required',
'email' => 'required|email',
'phone' => 'nullable',
'age'=>'required',
]);
Client::create($request->all());
dd($request->phone);
return redirect('/')->with('msg', 'Client Saved successfully!.');
}
the phone' => 'nullable', value will not insert in the database unless i update the existing values. I tried this command dd($request->phone); and it shows the correct value from the user input. Any idea why the value will be inserted as null on database?
This is the value output when i make the dd command
I tried this other code which works well but im trying to use the default create() function of laravel. This is the other code i did that works well:
public function storeClient()
{
$client = new Client();
$client->name = request('name');
$client->email = request('email');
$client->phone_number = request('phone');
$client->age = request('age');
$client->save();
return redirect('/')->with('msg','Client Saved successfully!');
}
first i did not like nullable here 'phone' => 'nullable',
then u should see what do you register in your Client table phone_number or phone,
$client->phone_number = request('phone');
i think you should rename your input name phone to phone_number and will work
When you are trying to use default create method the fields names must be same as in database.
$client->phone_number = request('phone');
this line works due to the name you entered manually.
to work with default create method change the name of field in database as phone.

Laravel increment column in updateOrCreate and get the model

I am trying to increment a column and updateorcreate a record in one query by doing so:
$model = Model::updateOrCreate([
'email' => $email
], ['received_at' => $received_at])->incremet('received_count');
This does the job as I wanted it too. It updates or create a record and increments the received_count column.
But after the query, I wanted to get the updated/created row, but when I log $model, it only logs 0 or 1. I can confirm that this is because of the ->increment().
But to be honest, I don't know any way how to increment the received_count column other than how I currently did it.
How do I achieve so that it updates or create a record, at the same time increments the received_count column, and after all of this, returns the updated/created object?
As much as posssible, I want this all in one query. Getting the model should be a memory.
$model = Model::updateOrCreate(['email' => $email], ['received_at' => $received_at]);
$model->increment('received_count');
$model->refresh(); // this will refresh all information for your model.
or you can simply:
$model = Model::updateOrCreate(['email' => $email], ['received_at' => $received_at]);
tap($model)->increment('id'); // this will return refreshed model.
just fresh model after incremet:
$model = Model::updateOrCreate([
'email' => $email
], ['received_at' => $received_at]);
$model->incremet('received_count');
$model->fresh();

How to use Rule:unique with array of values compared to another column in laravel?

i have a request for array of values and i validate it with the following code
$request->validate([
'doctor_id.*' => ['required'],
'doctor_id' => [Rule::unique('project_orders')->where(function ($query) use ($student) {
$query->where('student_id', $student->id);
})],
]);
but the unique validation doesn't work and the data was inserted to the table with duplication
i want the doctor_id field to be unique with the student_id column, what should be the correct rule?
any help please ?
First you need to do validation on database level, so you will add in your migration
$table->unique(['doctor_id', 'student_id']);
This will make sure that there will be no duplication for same doctor_id and student_id values
Then in your validation layer you will add
$request->validate([
'doctor_id.*' => 'unique:project_orders,doctor_id,NULL,id,student_id,'.$student->id,
]);
You can do the validation like this
$request->validate([
'doctor_id.*' => [ Rule::unique('project_orders', 'doctor_id')->where('student_id', $student->id) ]
]);

Pass array into a single column in Laravel

i am trying to pass some values into a single column in laravel database table.
The values are like this 20,45,67,89
but i want them to enter into the colume like this
===USER_ID====
20
45
67
89
I have tried like below, but not working..any suggestions ?
foreach ($request->val2 as $value){
$str_explode = explode(",",$value);
DB::table('retirement')->insertGetId([
'user_id' => $str_explode,
'amount' => $request->val1,
'week' => $request->week
]);
}
Hope this will work
foreach ($request->val2 as $value){
$str_explode = explode(",",$value);
$insert = [];
foreach($str_explode as $str){
$insert[] = [
'user_id' => $str,
'amount' => $request->val1,
'week' => $request->week
];
}
DB::table('retirement')->insert($insert);
I'm not sure i understood your question clearly, i'm assuming you want to insert array to a column:
did you try to set the column in migration to Json?
did you set the $casts in the model to json or array?
protected $casts = [ 'user_id' => 'array' ];
then when you do this, you can have an array added to that column like
Posts::create(['user_id'=>[1,2,3,4]]);
normally the user_id field is set to unsignedBigInt(), that type will not accept anything but integers, you gotta check the migration column type first.
explode() is returning an array, not a single value, that's why it will fail. Instead, you should loop through all values like this:
foreach ($request->val2 as $value){
$str_explode = explode(",",$value);
foreach($str_explode as $str){
DB::table('retirement')->insertGetId([
'user_id' => $str,
'amount' => $request->val1,
'week' => $request->week
]);
}
}
As a side advice, as you are not saving the id returned by insertGetID, you can simply use insert. Moreover, it's usually a good practice to use create because this way you will also save timestamps for created and updated.

Laravel send mail with multiple check box value

i'm trying to make inquiry form where costumer fill up form then check the value on the checkbox then once they submit form will send email to me listing all the information the customer selected, now problem is i want to change this[event_id,requirement_id] instead of id replace it with name those two id parameter is from my two model listed below.
Model:
Event:[id,name]
Requirement:[id,name]
Controller:
public function store(Request $request)
{
$summary=[
'name' => $request->fullname,
'email' => $request->email,
'company' => $request->company,
'event' => $request->event_id,
'requirement' => $request->requirement_id
];
return $summary;
Mail::send('emails.contact-message',[
],function($mail) use($summary){
$mail->from('myemail#gmail.com', 'tester');
$mail->to('myemail#gmail.com')->subject('Contact Message');
});
return redirect()->back();
}
This is the result of my return request:
{"name":"myname","email":"myemail#gmail.com","company":"mycompany","event":["1","2"],"requirement":["1","2"]}
As you can see the array Event has value of 1 and 2 i wanted to replace it with its name output should be [Wedding,Birthday] i'm sorry for my bad english hope you understand me..
Well, you'd need to pull the name from your models.
The following should do the trick:
$events = App\Event::whereIn('id', $request->event_id)
->get()
->pluck('name')
->toArray();
$requirements = App\Requirement::whereIn('id', $request->requirement_id)
->get()
->pluck('name')
->toArray();
Obviously, replace name in the above example with the actual name field in your models. This is just an example.
$events and $requirements will both be an array containing the names matching the ids you are supplying in your request.
You also need to change your $summary array as follows:
$summary = [
'name' => $request->fullname,
'email' => $request->email,
'company' => $request->company,
'event' => $events
'requirement' => $requirements
];

Resources