In laravel how to seed existing databse using array? - laravel

I want to seed existing database in my application.
here is db with data in it:
I made array in seeder and now I want to assign those values to my fields with one loop I guess;
This is migration:
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->char('maker');
$table->integer('model')->unique();
$table->string('type');
});
}
And here is my seeder, I tried something but it isn't working. it says "Undefined array key "A""
public function run()
{
$array = ['A', 1232, 'PC',
'A', 1233, 'PC',
'A', 1276, 'Printer',
'A', 1298, 'Laptop',
'A', 1401, 'Printer',
'A', 1408, 'Printer',
'A', 1752, 'Laptop',
'B', 1121, 'PC',
'B', 1750, 'Laptop',
'C', 1321, 'Laptop',
'D', 1288, 'Printer',
'D', 1433, 'Printer',
'E', 1260, 'PC',
'E', 1434, 'Printer',
'E', 2112, 'PC',
'E', 2113, 'PC'
];
foreach ($array as $key => $item){
Product::create([
'maker' => $array[$item],
'model' => $array[$item],
'type' => $array[$item]
]);
}
}

use this function for insert all data
for($i=0;i<size_of($array);$i++){
if(($i%3)==0){
DB::table('products')->insert([
'maker' =>$array[$i],
'model' => $array[$i+1],
'type' => $array[$i+2]
]);
}
}

Related

Ruby hash of hashes, how to get key if there is a key value match into the nested hashes

I have a ruby hash with this structure:
jotform = {
'1' => {
'name' => 'theGreat',
'order' => '1',
'text' => 'xxxxx',
'type' => 'control_head'
},
'3' => {
'name' => 'clickTo',
'order' => '2',
'text' => '<p>Final date to apply is August 29</p>',
'type' => 'control_text'
},
'4' => {
'name' => 'personalDetails',
'order' => '3',
'text' => 'Personal Details',
'type' => 'control_head'
},
'5' => {
'name' => 'name',
'order' => '4',
'sublabels' =>
'{"prefix":"Prefix","first":"First Name","middle":"Middle Name","last":"Last Name","suffix":"Suffix"}',
'text' => 'Name',
'type' => 'control_fullname',
'answer' => {
'first' => 'Example',
'last' => 'Example'
},
'prettyFormat' => 'Example'
},
'9' => {
'name' => 'country',
'order' => '5',
'text' => 'Country',
'type' => 'control_dropdown',
'answer' => 'Germany'
},
'10' => {
'name' => 'email',
'order' => '6',
'text' => 'Email',
'type' => 'control_email',
'answer' => 'picco#example.com'
},
'15' => {
'name' => 'pageBreak',
'order' => '8',
'text' => 'Page Break',
'type' => 'control_pagebreak'
},
'16' => {
'name' => 'contributions',
'order' => '9',
'text' => 'Contributions',
'type' => 'control_head'
}
}
This is a payload that I receive from jotform and I have to process in my app.
The issue is that I don't know the field order: this hash has some keys ('1', '2', …) that are equivalent to the form answer.
I must get the name in Pretty Format and the email, so I'm trying to get these values.
Here the email has key '10' and the name has key '5' but they can change in the next form.
I try with
jotform.select { |_key, hash| hash['name'] == 'email' }
But it returns
{
'10' => {
'name' => 'email',
'order' => '6',
'text' => 'Email',
'type' => 'control_email',
'answer' => 'example#example.com'
}
}
I need to get the key ('10') if there is a match into this key's value but I cannot understand how.
From the result of your select call:
h = jotform.select{ |key, hash| hash["name"] == "email" }
You can get the key via:
h.keys.first
#=> "10"
And the value via:
h.values.first["answer"]
#=> "example#example.com"
first is needed because there could (in theory) be multiple entries for email.
Well, that's a weird format.
I'm not sure I understand it, but assuming that name is unique, you could reindex your hash and use name as key:
new_data = jotform.map do |id, h|
key = h.delete 'name'
[key, h.merge('id' => id)]
end.to_h
The new format looks like :
{"theGreat"=>
{"order"=>"1", "text"=>"xxxxx", "type"=>"control_head", "id"=>"1"},
"clickTo"=>
{"order"=>"2",
"text"=>"<p>Final date to apply is August 29</p>",
"type"=>"control_text",
"id"=>"3"},
"personalDetails"=>
{"order"=>"3",
"text"=>"Personal Details",
"type"=>"control_head",
"id"=>"4"},
"name"=>
{"order"=>"4",
"sublabels"=>
"{\"prefix\":\"Prefix\",\"first\":\"First Name\",\"middle\":\"Middle Name\",\"last\":\"Last Name\",\"suffix\":\"Suffix\"}",
"text"=>"Name",
"type"=>"control_fullname",
"answer"=>{"first"=>"Example", "last"=>"Example"},
"prettyFormat"=>"Example",
"id"=>"5"},
"country"=>
{"order"=>"5",
"text"=>"Country",
"type"=>"control_dropdown",
"answer"=>"Germany",
"id"=>"9"},
"email"=>
{"order"=>"6",
"text"=>"Email",
"type"=>"control_email",
"answer"=>"picco#example.com",
"id"=>"10"},
"pageBreak"=>
{"order"=>"8",
"text"=>"Page Break",
"type"=>"control_pagebreak",
"id"=>"15"},
"contributions"=>
{"order"=>"9", "text"=>"Contributions", "type"=>"control_head", "id"=>"16"}}
No information has been lost, and it should be easier to access. In order to get the email address, you can simply use:
new_data["email"]["answer"]
#=> "picco#example.com"

Insert value list does not match column list on Laravel nullable()

I have a DB table with the following structure:
Table Migration:
Schema::create('initiatives', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->unsignedBigInteger('initiative_group_id');
$table->string('initiative_owner')->nullable();
$table->date('start_date')->nullable();
$table->date('end_date')->nullable();
$table->timestamps();
$table->foreign('initiative_group_id')
->references('id')
->on('initiative_groups')
->onDelete('cascade');
});
Now, I'm trying to seed that table with some rows:
Database seeder
public function run()
{
DB::table('initiatives')->insert([
['name' => 'A1', 'initiative_group_id' => 1, 'initiative_owner' => 'Person A'],
['name' => 'B1', 'initiative_group_id' => 2, 'initiative_owner' => 'Person B'],
['name' => 'B2', 'initiative_group_id' => 2],
['name' => 'D1', 'initiative_group_id' => 4, 'initiative_owner' => 'Person C'],
['name' => 'D2', 'initiative_group_id' => 4, 'initiative_owner' => 'Person C'],
['name' => 'D3', 'initiative_group_id' => 4, 'initiative_owner' => 'Person C'],
['name' => 'E1', 'initiative_group_id' => 5],
]);
}
I get the following error:
SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesn't match value count at row 12;
So I know that I am selectively including and excluding some columns in these inserts (sometimes I have an initiative_owner and sometimes not), but can I not specify not to insert some columns as I've set them to nullable? Is there a way to do that?
If you are doing multiple insertions in one go from seeder, but the length of all arrays must be the same.
DB::table('initiatives')->insert([
['name' => 'A1', 'initiative_group_id' => 1, 'initiative_owner' => 'Person A'],
['name' => 'B1', 'initiative_group_id' => 2, 'initiative_owner' => 'Person B'],
['name' => 'B2', 'initiative_group_id' => 2], //initiative_owner is missing
['name' => 'D1', 'initiative_group_id' => 4, 'initiative_owner' => 'Person C'],
['name' => 'D2', 'initiative_group_id' => 4, 'initiative_owner' => 'Person C'],
['name' => 'D3', 'initiative_group_id' => 4, 'initiative_owner' => 'Person C'],
['name' => 'E1', 'initiative_group_id' => 5], //initiative_owner is missing
]);
You can set them null but don't skip.
The second option you can insert two different arrays.
DB::table('initiatives')->insert([
['name' => 'A1', 'initiative_group_id' => 1, 'initiative_owner' => 'Person A'],
['name' => 'B1', 'initiative_group_id' => 2, 'initiative_owner' => 'Person B'],
['name' => 'D1', 'initiative_group_id' => 4, 'initiative_owner' => 'Person C'],
['name' => 'D2', 'initiative_group_id' => 4, 'initiative_owner' => 'Person C'],
['name' => 'D3', 'initiative_group_id' => 4, 'initiative_owner' => 'Person C'],
]);
DB::table('initiatives')->insert([
['name' => 'B2', 'initiative_group_id' => 2],
['name' => 'E1', 'initiative_group_id' => 5],
]);

Flatten laravel nested relationship (parent to descendants)

I have a parent children relationship on my model. What I want is to flatten all those collection including all those descendants of parent.
[
{
'name': 'Parent',
'another_array' => [
{
'name': 'Another Array Name'
}
],
'children': [
{
'name': 'First Child',
'address': 'lorem ipsum',
'contact_no': '92390',
'another_array' => [
{
'name': 'Another Array Name'
}
],
'children': [
{
'name': 'First Descendant',
'address': 'lorem ipsum',
'contact_no': '92390',
'children': [
{
'name': 'Descendant Child',
'address': 'lorem ipsum',
'contact_no': '92390',
'children': [
{
'name': 'Last Descendant',
'address': '',
'contact_no': '',
'children': []
}
]
}
]
}
]
}
]
}
]
I tried the code below. However it only displays the second depth of children. It does not display the next children of the collection.
User.php
public function parent()
{
return $this->belongsTo(User::class, 'id', 'parent_id');
}
public function children()
{
return $this->hasMany(User::class,'parent_id', 'id');
}
public function descendants()
{
return $this->children()->with('descendants');
}
UsersController.php
public function index()
{
$parent = User::find(1);
$parent->with('descendants')->find($parent->id);
$descendants = $this->traverseTree($parent->descendants);
return response($descendants);
}
protected function traverseTree($subtree)
{
$descendants = collect([]);
foreach ($subtree->descendants as $descendant) {
$descendants->push($descendant);
if($descendant->descendants instanceof Collection) {
foreach ($descendant->descendants as $node) {
$this->traverseTree($node);
$descendants->push($node);
}
}
}
return $descendants;
}
Desired Output
[
{
'name': 'Parent',
'address': 'lorem ipsum',
'contact_no': '92390'
},
{
'name': 'First Child',
'address': 'lorem ipsum',
'contact_no': '92390'
},
{
'name': 'First Descendant',
'address': 'lorem ipsum',
'contact_no': '92390',
},
{
'name': 'Descendant Child',
'address': 'lorem ipsum',
'contact_no': '92390',
},
{
'name': 'Last Descendant' ,
'address': '',
'contact_no': '',
}
]
I am looking forward for your help.
from your collection response convert it to an array by chaining the toArray() method so you output becomes and a multi-dimensional array instead of nested objects as shown below...
$my_array = [
'name' => 'Parent',
'children' => [
'name' => 'First Child',
'address' => 'lorem ipsum',
'contact_no' => '234',
'children' => [
'name' => 'First Descendant',
'address' => 'lorem ipsum',
'contact_no' => '567',
'children' => [
'name' => 'Descendant Child',
'address' => 'lorem ipsum',
'contact_no' => '8890',
'children' => [
'name' => 'Last Descendant',
'address' => '',
'contact_no' => '',
'children' => []
]
]
]
]
];
then you can use this helper function below:
protected function _flattened($array)
{
$flatArray = [];
if (!is_array($array)) {
$array = (array)$array;
}
foreach($array as $key => $value) {
if (is_array($value) || is_object($value)) {
$flatArray = array_merge($flatArray, $this->_flattened($value));
} else {
$flatArray[0][$key] = $value;
}
}
return $flatArray;
}
when you dump the $result = $this->_flattened($my_array);, you will have output like...
[
0 => [
"name" => "Parent"
],
1 => [
"name" => "First Child",
"address" => "lorem ipsum"
"contact_no" => "234"
],
2 => [
"name" => "First Descendant"
"address" => "lorem ipsum"
"contact_no" => "567"
],
3 => [
"name" => "Descendant Child"
"address" => "lorem ipsum"
"contact_no" => "8890"
],
4 => [
"name" => "Last Descendant"
"address" => ""
"contact_no" => ""
],
];

Aloha editor - contenthadler settings per editable not making any changes

I have multiple (6) editables with two different classes (.html_edit_simple, .html_edit_advanced) on website and I want to divide them by class and each to have its own contentHandler settings.
But no matter what I try, only the default settings are loaded.
The ones defined under window.Aloha.settings.contentHandler.handler.sanitize don't apply at all.
The settings code that I use is the following:
(function(window, undefined) {
if (window.Aloha === undefined || window.Aloha === null) {
window.Aloha = {};
}
window.Aloha.settings = { sidebar: { disabled: true } };
window.Aloha.settings.contentHandler = {
insertHtml: [ 'word', 'generic', 'oembed', 'sanitize' ],
initEditable: [ 'sanitize' ],
getContents: [ 'blockelement', 'sanitize', 'basic' ],
sanitize: 'relaxed', // relaxed, restricted, basic,
allows: {
elements: ['strong', 'em', 'i', 'b', 'blockquote', 'br', 'cite', 'code', 'dd', 'div', 'dl', 'dt', 'em', 'i', 'li', 'ol', 'p', 'pre', 'q', 'small', 'strike', 'sub', 'sup', 'u', 'ul', 'h1', 'h2', 'h3', 'h4', 'h5', 'img', 'video', 'audio']
},
handler: {
generic: {
transformFormattings: false
},
sanitize: {
'.html_edit_simple': { elements: [ 'b', 'i', 'strong', 'em', 'strike', 'u', 'a' ] },
'.html_edit_advanced': { elements: [ 'b', 'i', 'strong', 'em', 'strike', 'u', 'a', 'br', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'sub', 'sup', 'ul', 'ol', 'li', 'div', 'img', 'video', 'audio' ] }
}
}
}
})(window);
I made a console log just before Aloha.ready and everything is loaded correctly.
So where could be the issue.

Consolidating duplicate array items

I have an array of hashes...
array = [
{
'keyword' => 'A',
'total_value' => 50
},
{
'keyword' => 'B',
'total_value' => 25
},
{
'keyword' => 'C',
'total_value' => 40
},
{
'keyword' => 'A',
'total_value' => 10
},
{
'keyword' => 'C',
'total_value' => 15
}]
I need to consolidate the hashes with an identical keyword value. By consolidate, I mean combine total_values. For example, after consolidation of the above array, there should only be one hash with 'keyword' => 'A' with a 'total_value => 60
array = [
{
'keyword' => 'A',
'total_value' => 50
},
{
'keyword' => 'B',
'total_value' => 25
},
{
'keyword' => 'C',
'total_value' => 40
},
{
'keyword' => 'A',
'total_value' => 10
},
{
'keyword' => 'C',
'total_value' => 15
}]
m = array.inject(Hash.new(0)) do |hs,i|
hs[i['keyword']] += i['total_value']
hs
end
p m
Output:
{"A"=>60, "B"=>25, "C"=>55}
By consolidate, I mean combine total_values. For example, after consolidation of the above array, there should only be one hash with 'keyword' => 'A' with a 'total_value => 60
Here is how it can be done:
m = array.each_with_object(Hash.new(0)) do |h,ob|
if h['keyword'] == 'A'
h['total_value'] += ob['total_value']
ob.update(h)
end
end
p m
#=> {"keyword"=>"A", "total_value"=>60}
A simple method is doing this as you add items to a collection. Start to add an item, check if keyword is there. if (a) it's there, then just add new item's total_value to its. else (b) add new item to the collection.
array.group_by{|h| h["keyword"]}
.map{|k, v| {
"keyword" => k,
"total_value" => v.map{|h| h["total_value"]}.inject(:+)
}}

Resources