I want to update all users in my database with an age value which I get from my request.
How do I manage this?
I somehow need the current value in the db and multiple it.
DB::table('customers')
->update([
'age' => DB::raw('column1 * 2'),
]);
Let's assume that the name of the field in your $request is multiple, you can iterate over your customer records and update each of them, applying your multiple value to their age:
// grab the `multiple` value from your request
$multiple = $request->get('multiple');
// get all your customers, loop over them and update each record
Customer::all()->each(function ($customer) use ($multiple) {
$customer->update(['age' => $customer->age * $multiple]);
});
If you want to use the QueryBuilder rather than Eloquent, then you can do the following:
DB::table('customers')->get()->each(function ($customer) use ($multiple) {
DB::table('customers')
->where('id', $customer->id)
->update(['age' => $customer->age * $multiple]);
});
Maybe you want to update a column based on a value as an input that is provided by the user.
Also notice I have used double quotation.
DB::table('your_table')
->where('some_column', $someValue)
->update(array(
'column1' => DB::raw("column1 * $your_input_variable")
));
To avoid the N+1 problem, I will advise you use the Eloquent's "WhereIn" method. The idea is that you build the list of items to update within the logic instead of hitting the db server N no of times in a loop as others suggested.
$itemTypes = [1, 2, 3, 4, 5]; //loop through your request payload and make this list.
$columns = [[
'name' => 'Ezugudor',
'age' => '18',
'rank' => 13
],[
'name' => 'Mathew',
'age' => '13',
'rank' => 1
]]; //loop through your request payload and make this list.
ItemTable::whereIn('item_id', $itemTypes)
->update($columns);
A cleaner way to do that
$items = Model::all();
$insertData = collect();
foreach ($items as $item)
{
$insertData->push([
'id' => $item['id'],
'otherstuff' => $item['name']),
'age' => $item['age'] * 2,
'more other stuff' => $item['itmPrice'],
]);
}
// chunks of 1000 insert into db
foreach ($insertData->chunk(1000) as $chunk)
{
DB::table('table_name')
->upsert(
$chunk->toArray(), // array of data that is going to be inserted or updated
['id'], // array of the column names that should be used for finding the updatable row
[ 'age'] // values that will be updated
);
}
upsert docs here
Related
I have a function in JSX that stores value gotten from a database thus:
const data = JSON.parse(xhr.responseText);
this.setState({ data: data });
The response format is:
[{"id":4,"name":"Avengers: Infinity War","year":2018},{"id":5,"name":"Thor: Ragnarock","year":2017},{"id":6,"name":"Black Panther","year":2018},{"id":7,"name":"Star Wars: The Rise of Skywalker","year":2019}]
However, I am trying to use a react table control that expects the data to be in this format:
const data = [
['1st column', '2nd column', '3rd column'],
['1st cell', '2nd cell', '3rd cell']
]
render() {
<ReactTabllist
data={data}
property={property} />
}
So I need to turn the JSON into an javascript array of arrays. What is a good way to do this?
const data = this.state.data.map(movie => ( /* what goes here? */ ));
As per I understand, you need to get every property in the JSON and then put the values of every element into the data-react property.
So, first you would need to make sure, the response from the database is well formatted, and that every element in the json-parsed responseText is the same as the rest of them.
With that into account:
const formattedData = this
.state
.data
.map(movie => Object.keys(movie).map(key => movie[key]));
And that formattedData is what you want to pass as react-attribute of data={formattedData}
Alternatively, if you don't care about the keys of the movie whatsoever, you could do as #Madmadi has suggested:
const formattedData = this
.state
.data
.map(movie => Object.values(movie));
I have the following php array in a laravel variable called $salaries which is passed to a blade view:
array:4 [▼
2 => "£8, Per hour"
3 => "£10, Per hour"
23 => "Up to £10000, Per annum"
24 => "£10,000 - £15,000, Per annum"
]
In my blade view I have a drop which when changed, I want to load a select2 dropdown with the above options. Below is my code:
$(document).on("change", ".js-selector", function() {
var options = {!! json_encode($salaries) !!};
$("#salary_list").empty().select2({
data: options
});
})
However nothing is getting loaded into the dropdown. So I've narrowed it down to the options data for select2 not being in the correct format.
When I output options variable to console I'm getting the following object as opposed to a javascript array?
{2: "£8, Per hour", 3: "£10, Per hour", 23: "Up to £10000, Per annum", 24: "£10,000 - £15,000, Per annum"}
How do I transform the options into correct format for the select2 data?
You have to transform your data to the correct format, here you can see the correct data format:
var data = [
{
id: 2,
text: '£8, Per hour'
},
{
id: 3,
text: '£10, Per hour'
}
];
You could pass the array in the correct format to the view, something like:
$salaries = \App\Models\Salary::all(); // eloquent collection
$salaries = $salaries->map(function ($salary) {
return ['id' => $salary->id, 'text' => $salary->text];
})->toArray();
It would give result in something like this:
array:1 [▼
0 => array:2 [▼
"id" => 2
"text" => "£8, Per hour"
]
0 => array:2 [▼
"id" => 3
"text" => "£10, Per hour"
]
]
Or you can transform the array in javascript, the Select2 documentation explains here how you can transform your data:
Select2 requires that the id property is used to uniquely identify the
options that are displayed in the results list. If you use a property
other than id (like pk) to uniquely identify an option, you need to
map your old property to id before passing it to Select2.
If you cannot do this on your server or you are in a situation where
the API cannot be changed, you can do this in JavaScript before
passing it to Select2:
var data = $.map(yourArrayData, function (obj) {
obj.id = obj.id || obj.pk; // replace pk with your identifier
return obj;
});
In your case it would be something like this:
$(document).on("change", ".js-selector", function() {
var options = {!! json_encode($salaries) !!};
var data = $.map(options, function (value, key) {
return {id: key, text: value};
});
$("#salary_list").empty().select2({
data: data
});
})
exactly as Serhii said, simply extract the values from you associative array before encoding it:
$(document).on("change", ".js-selector", function() {
var options = {!! json_encode(array_values($salaries)) !!};
$("#salary_list").empty().select2({
data: options
});
})
Your array must have the structure like this:
[
[
'id' => 2,
'text' => "£8, Per hour"
],
[
'id' => 3,
'text' => "£10, Per hour"
],
[
'id' => 23,
'text' => "Up to £10000, Per annum"
],
[
'id' => 24,
'text' => "£10,000 - £15,000, Per annum"
],
]
https://select2.org/data-sources/arrays
I'm trying to perform an update command with sequelize on rows in a postgres database. I need to be able to update multiple rows that have different conditions with the same value.
For example, assume I have a user table that contains the following fields:
ID
First Name
Last Name
Gender
Location
createdAt
Assume, I have 4 records in this table, I want to update records with ID - 1 and 4 with a new location say Nigeria.
Something like this: SET field1 = 'foo' WHERE id = 1, SET field1 = 'bar' WHERE id = 2
How can I achieve that with sequelize?
You can update multiple record at a time , but same updates for all records
, if you want to make different updates for different conditons then you have to run that multiple time
Example :
This will update fields1 to foo , where id is 1 or 4
let ids = [1,4];
Your_model.update({ field1 : 'foo' },{ where : { id : ids }});
This will update field1 to foo if id is 1 , and field1 to bar if id is 4
Your_model.update({ field1 : 'foo' },{ where : { id : 1 }});
Your_model.update({ field1 : 'bar' },{ where : { id : 4 }});
Hope this will clear all your doubts.
You can update multiple rows following your conditions, and to do that the operators are very helpful.
Look here: http://docs.sequelizejs.com/manual/querying.html (operators)
const { Op } = Sequelize;
DisplayMedia.update(
{
field: 'bar'
},
{
where: {
id: {
[Op.in]: [1, 10, 15, ..] // this will update all the records
} // with an id from the list
}
}
)
There is all kinds of operators, including the range operators, or like operator ...etc
Also one of the important questions when it come to update, is how to update all rows?
Not including where results in an error "Missing where attribute in the options parameter passed to update".
The answer is in the code bellow: provide a where with an empty object.
await DisplayMediaSequence.update({
default: false
}, {
where: {}, // <-- here
transaction
});
await DisplayMediaSequence.update({
default: true <-- after all turned to false, we now set the new default. (that to show a practical expample) -->
}, {
where: {
id
},
transaction
});
we planning to save different values for same fields in multiple row there is a possible for getting all field values are same in database.
using for loop
const {idArray,group_id} = params;
for(const item of idArray){
const response = await Your_model.findOne({ where:{group_id,user_id:null}, order: [['id', 'DESC']] });
await response.update({user_id:item});
}
Edit 2 : even better, multiple values works
Actually, one simply has to give a "value" field that fills the box. No need for the "id/label" field, but value field is required. This is working :
foreach ($queries as $query)
{
$results[] = [
'zip' => $query->zip,
'value' => $query->commune,
'libelle' => $query->libelle,
'lieudit' => $query->lieudit
];
}
return Response::json($results);
Edit : here is the solution, thanks to Adyson's answer
The script should be json formatted and returning
An array of objects with label and value properties:
[ { label: "Choice1", value: "value1" }, ... ]
(jQuery API documentation)
So, modifying the PHP script like this will work :
foreach ($queries as $query)
{
$results[] = [
'id' => $query->zip,
'value' => $query->commune,
];
}
return Response::json($results);
Original question
Using Jquery Autocomplete, querying a script.
The list shows as many rows as there are results (when I set my script to return X results, there are X rows as well in the list) :
But it doesn't fill the rows with the data. What could have gone wrong there ?
The data returned is some json :
Request URL:http://localhost:8000/search/autocomplete?term=750
Request Method:GET
Status Code:200 OK
Remote Address:127.0.0.1:8000
Response Headers
view source
Cache-Control:no-cache
Connection:close
Content-Type:application/json
Date:Tue, 15 Nov 2016 14:53:07 GMT
Host:localhost:8000
And here is the data :
[{"zip":"75004","commune":"PARIS 04","libelle":"PARIS","lieudit":""},
{"zip":"75005","commune":"PARIS 05","libelle":"PARIS","lieudit":""},
{"zip":"75003","commune":"PARIS 03","libelle":"PARIS","lieudit":""},
{"zip":"75006","commune":"PARIS 06","libelle":"PARIS","lieudit":""},
{"zip":"75008","commune":"PARIS 08","libelle":"PARIS","lieudit":""},
{"zip":"75012","commune":"PARIS 12","libelle":"PARIS","lieudit":""},
{"zip":"75015","commune":"PARIS 15","libelle":"PARIS","lieudit":""},
{"zip":"75016","commune":"PARIS 16","libelle":"PARIS","lieudit":""},
{"zip":"75017","commune":"PARIS 17","libelle":"PARIS","lieudit":""},
{"zip":"75010","commune":"PARIS 10","libelle":"PARIS","lieudit":""},
{"zip":"75018","commune":"PARIS 18","libelle":"PARIS","lieudit":""},
{"zip":"75001","commune":"PARIS 01","libelle":"PARIS","lieudit":""},
{"zip":"75009","commune":"PARIS 09","libelle":"PARIS","lieudit":""},
{"zip":"75014","commune":"PARIS 14","libelle":"PARIS","lieudit":""},
{"zip":"75002","commune":"PARIS 02","libelle":"PARIS","lieudit":""},
{"zip":"75007","commune":"PARIS 07","libelle":"PARIS","lieudit":""},
{"zip":"75011","commune":"PARIS 11","libelle":"PARIS","lieudit":""},
{"zip":"75013","commune":"PARIS 13","libelle":"PARIS","lieudit":""},
{"zip":"75019","commune":"PARIS 19","libelle":"PARIS","lieudit":""},
{"zip":"75020","commune":"PARIS 20","libelle":"PARIS","lieudit":""}]
Here is my JS :
$(function(){
$( "#fromzip" ).autocomplete({
source: "/search/autocomplete",
dataType: 'json',
minLength: 3,
});
});
The HTML :
<input
id="fromzip"
name="fromzip"
type="text"
class="form-control"
placeholder="69003"
pattern=".{5}"
title="5 numbers zip"
maxlength="5"
required >
And the PHP (Laravel Input, DB and Response facades) :
public function autocomplete(){
$term = Input::get('term');
$results = array();
$queries = DB::table('zips')
->where('zip', 'LIKE', $term.'%')
->orWhere('libelle', 'LIKE', $term.'%')
->take(30)->get();
foreach ($queries as $query)
{
$results[] = [ 'zip' => $query->zip,
'commune' => $query->commune,
'libelle' => $query->libelle,
'lieudit' => $query->lieudit];
}
return Response::json($results);
}
Have a look at http://api.jqueryui.com/autocomplete/#option-source. It states that the data must be in the format
[ { label: "Choice1", value: "value1" }, ... ]
Your sample data items don't have either of those properties (label or value).
You can modify your server-side script to output the right format, or if you can't/won't do that, you could use the source-as-a-function option in the plugin to write a function that transforms the data.
I currently have the following data structure in Redis
client.hmset('user:' + user.id, 'id', user.id, 'user', JSON.stringify(meta));
client.zadd(['user:user_by_created_time', meta.created_time, 'user:' + user.id]);
client.zadd(['user:user_by_age', meta.age, 'user:' + user.id]);
I then when to get the first 10 users sorted by age, when there are more than 10, I should be able to pass an offset that allows me to use pagination.
What I currently have is the following
client.zrangebyscore(['user:user_by_age', '-inf', '+inf'], (err, results) => {
const multi = client.multi();
results.forEach(result => {
multi.hgetall(result);
});
multi.exec((err, results) => { ... });
});
I'm a bit stuck on how to continue with this, I know it's possible to sort a list, but I can't figure out how to only get 10 users after a specific offset.
I'm using the Node Redis client: https://github.com/NodeRedis/node_redis
To paginate with sorted sets use ZRANGE, not ZRANGEBYSCORE. The arguments are the ranks, so to get the first 10 users you use ZRANGE user:user_by_age 0 9, to get the next 10 you use ZRANGE user:user_by_age 10 19, etc.