Laravel Replace existing DB value - Favourites - php

I am trying to setup a favourites button on an article. The following code works ...
public function favouriteNotfavouriteArticleParent(Request $request){
$data = [];
$data['user_id'] = Auth::id();
$data['person_id'] = GetPersonData()['id'];
$data['article_id'] = $request->get('article_id');
$data['action'] = $request->get('action');
UserFavourites::updateOrCreate($data,$data);
}
However, i want it to firstly check for any existing values set for that article ID. If it has favourite set and notfavourite is clicked, it should remove the favourite table row.
At the minute it just adds a row for favourite and notfavourite. I've attached a screenshot of the current sql behaviour.
Any help is massively appreciated!

UpdateOrCreate takes two arguments. The first argument is an array of attributes to look for and the second argument is an array of attributes to change. If there isn't a row in the database that has attributes from the first array the arrays will essentially be combined to make a new row in the database.
To achieve what you're after you could do the following:
UserFavourites::updateOrCreate([
'article_id' => $request->input('article_id'),
'user_id' => auth()->id(),
], [
'person_id' => GetPersonData()['id'],
'action' => $request->input('action'),
]);
The above will look for a row that matches the article_id and user_id and then either update the person_id and action for that row or (if the row doesn't exist) create a new row with all the attributes.

Related

Laravel update specific column in database 'cost' and add supplier_id to another database table

i'm working with sensitive data hope you can help find if there any wrong in code's writing
i have list of suppliers in my database i added column 'cost'
i'm trying to update and insert cost for existing suppliers from specific query
and i created model and migration to get foreign keys too by adding the puled supplier id from the query
....
$suppliers_data = $suppliers_query->fetchall(PDO::FETCH_ASSOC);
foreach ($suppliers_data as $supplier_data) {
$supplier_name = $supplier_data['supplier_name'];
$cost_rate = $supplier_data['Cost'];
if (!Supplier::where('supplier', $supplier_name)->exists()) {
Supplier::insert([
'supplier' => $supplier_name,
'cost_rate' => $cost_rate
]);
} else {
Supplier::update([
'cost_rate' => $cost_rate // does this will update cost for the current supplier ?
]);
}
$supplier_id = Supplier::where('supplier', $supplier_name)->pluck('supplier_id');
Test::insert($supplier_id);
}
$supplier_count = test::count();
Test::update(['test_data_count' => $supplier_count]);
Updating table data with supplier name is not correct here I believe. Instead of using supplier name in where condition using particular supplier id is recommended for better application. Names can be duplicate so its not a good idea to use supplier name in where.
In your current code I have 2 things to say :
You need to add where in update eloquent to work properly
Supplier::where('supplier', $supplier_name)
->update([
'cost_rate' => $cost_rate // this will update cost for the current supplier
]);
Or to minimalize the code you can use updateorCreate method instead of making insert and update in the if() else() condition
Supplier::updateOrCreate(
['supplier' => $supplier_name],
['cost_rate' => $cost_rate]
);

Laravel Eloquent - bulk update with whereIn array

I'm working on a project where I need to update many rows at once per coin Id.
in order to update all coins values, Im getting them all from the API, so for example I have back:
$coinsList= [[id="bitcoin", symbol="btc", name="Bintcoin"],[id="etherium", symbol="eth", name="Etherium"]];
and the database table columns is the following:
**| id | coin_id | symbol | name |**
now, I want to update all values to the database, according to the id only, so this is what I did:
// first get ids from my table
$exist_ids = Coinlist::all('coin_id')->pluck('coin_id')->toArray();
//get all ids to update (to ignore other ids):
$updatable_ids = array_values(array_intersect($exist_ids, $allCoinIds));//result for example is: array("bitcoin","etherium");
//and now, update the database:
Coinlist::whereIn('coin_id', $updatable_ids)
->update([
'symbol' => $coinsList[$key]['symbol'],
'name' => $coinsList[$key]['name'],
'updated_at' => now()
]);
the problem is, I don't have the "$key" in order to update the right row, what am I missing here?
Thanks!
Here is a good way to solve it:
in the beginning, I used this library: https://github.com/mavinoo/laravelBatch
to update many dynamic rows, but it was really slow, then thanks to Yasin, I moved to: https://github.com/iksaku/laravel-mass-update and now it works way better.
the implementation is simple, add a simple code to the Model class, then add:
User::massUpdate(
values: [
['username' => 'iksaku', 'name' => 'Jorge González'],
['username' => 'gm_mtz', 'name' => 'Gladys Martínez'],
],
uniqueBy: 'username'
);
while uniqueBy is the key for the row, and add other columns values to change them dynamically.

How to get the inserted id of create() method in laravel?

I'm trying to get the last inserted id made from create() eloquent in laravel.
Here's my laravel code
$product = ProductModel::create([
'prodCode' => $prodCode,
'prodTitle' => $dataProducts->prodTitle,
'prodDesc' => $dataProducts->prodDesc,
'attachment' => "images/products/".$attachment,
'prodSize' => $dataProducts->prodSize,
'prodCategory' => $dataProducts->prodCategory,
'prodPrice' => $dataProducts->prodPrice,
'created_by' => auth()->user()->id
]);
I will use this last inserted id for another query with the same function.
Is it possible to do it with this way of saving data, or do I need to convert this code to another efficient way?
The create function of a model returns new record.
Very easily:
$product = ProductModel::create([...]);
// last inserted id
$lastInsertedId = $product->$idField;
Well in this case your are doing right !
use print_r($product->id) to see the last inserted id if the field name is id

Laravel 5.2 - Insert n number rows to database with one submit request & custom validation message with row number

I am developing a simple task management web application using laravel. The requirement states that we need to save the general information such as TaskDate, AssignedTo in a taskinfo table. List of tasks for one specific person are saved in another table called tasks. The tasks table has TaskDetailID (PK), TaskID (FK from the above table), TaskDescription, HoursRequired, etc...
The form allows users to add as many rows as they can which means a person could get assigned unlimited amount of tasks.
My problem now is saving the tasks data in the table. I've successfully saved the data for the taskinfo table, and i can even save the data for the table but only when it's one column.
Here is my store function on TaskInfoController
public function store(Request $request)
{
$validator = Validator::make(
$request->all(),
[
'TaskDate.*' => 'required',
'AssignedTo.*' => 'required',
]
,
[
'TaskDate.*.required' => 'Task Date is required.',
'AssignedTo.*.required' => 'Please assign the task to someone.',
]
);
if ($validator->fails())
{
//redirect errors to mars
}
$taskinfo = new TaskInfo();
$taskinfo->TaskDate = Carbon::createFromFormat("m/d/Y", $request->input('TaskDate'));
$taskinfo->TaskAssignedTo = $request->input('TaskAssignedTo');
// Some more columns here
$taskinfo->Save();
// Now for the tasks table
$tasksbulkinsert = array();
foreach ($request->input('TaskDescription') as $taskdescription)
{
$tasksbulkinsert[] = array('TaskID' => Uuid::uuid4(), 'TaskDescription' => $taskdescription);
}
Task::insert($tasksbulkinsert);
return redirect()->action('TaskInfoController#index')->with('flash_message', 'Successfully Saved!');}
The above code actually works perfectly but i don't know how i can insert the HoursRequired, or any additonal value with the corresponding taskdescription on the tasks table.
I tried a few approaches
having an incremental count such as i++ to know which row index (so to speak) of the taskdescription the query is currently procession, and having another foreach loop with it's own counter for the hoursrequired input and getting the value where the taskdescription's counters is equal to the hoursrequired counter. But it didn't work and even if it did, i don't think having multiple foreach loops for every column is good for performance.
Having different arrays with their own foreach loop to get the values from the inputs and then somehow merge the arrays.
Here is my HTML form
<input class="form-control" name="TaskDescription[]" type="text">
<input class="form-control" name="HoursRequired[]" type="text">
Main Question.
How can I save the TaskDescription and the HoursRequired into the database with one query.
Not so important question
The array validation at the top works but is there a way to have an error message that states the row of the error.
For example, Date is required for row number n.
You can simply:
foreach ($request->input('TaskDescription') as $i=>$taskdescription)
{
$tasksbulkinsert[] = array(
'TaskID' => Uuid::uuid4(),
'TaskDescription' => $taskdescription,
'HoursRequired' => $request->input('HoursRequired')[$i]
);
}
For your second question:
$messages = [];
foreach($this->request->get('TaskDescription') as $key => $val)
{
$messages['TaskDescription.'.$key.'.required'] = 'TD is required for row $key';
$messages['some_field.'.$key.'.some_rule'] = 'some_field custom message on row $key';
}
$validator = Validator::make(
$request->all(),
[
'TaskDate.*' => 'required',
'AssignedTo.*' => 'required',
]
,
$messages;

How to clear $this to insert more records in CodeIgniter?

With CI, I want to insert one record in User table and one in Post table. Below is a brief of my code (two tables will have multiple columns, and I just use one as example).
$this->username=$user;
$this->db->insert('User',$this);
$this->title='my first post';
$this->db->insert('Post', $this);
However, the second insert will be something like "insert into Post (user, title) values ('$user', 'my first post'). And an error is reported that unknown column user in Post.
How can I clear the members in $this before inserting the next records (in another table)?
This happening becouse of
$this->username=$user;
You probably need to use
$this->db->insert('Post', $this->title);
And before you insert, set in title anything you want, but not
$this->db->insert('Post', $this);
However if you still want to work with an object, more information how to do this properly you can find here, http://ellislab.com/codeigniter/user-guide/database/active_record.html#insert
CI used array as the second argument in the insert method. The index will be the column name and the value referred by the index will be the value to be inserted. What you did was you just keep adding into the $this array.
When you first add username the array will look like this(neglecting the db) inside $this :
array( 'username' => $user );
When you add the title, it will become like this:
array( 'username' => $user, 'title' => 'my first post');
See how the previous entry still in there.
You can just unset($this->username);
or you can use another variable to hold your data instead of $this. Example:
$data = array('username' => $user);
$this->db->insert('User',$data);
$data = array('title' => 'my first post');
$this->db->insert('Post',$data);
And you can insert into two columns like this:
$data = array('username' => $user, 'description' => 'i am sleepy');
$this->db->insert('User',$data);
Hope my answer can help you.

Categories