In mongoDB, I have a table product :
{
"_id" : ObjectId("61e93a99667ad949974948fb"),
"listProduct" : [
{
"_id" : "61e93aceebadb38d243fa321",
"name" : "Product 1",
"order" : 1,
"childProduct" : [
{
"_id" : "61e93aceebadb38d243fa322",
"name" : "Samsung",
"description" : "New Samsung",
"productOn" : 1676351448
},
{
"_id" : "61ee808140451a00b4eee93c",
"name" : "Iphone",
"description" : "New Iphone",
"productOn" : 1676605213
},
],
}
],
}
In Models:
<?php
namespace App\Models\Backend\Mongo;
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Product extends Eloquent
{
protected $connection = 'mongodb';
protected $collection = 'product';
protected $guarded = ['_id'];
protected $dateFormat = 'U';
protected $fillable = [
'listProduct',
];
}
And in the laravel controller, I update the productOn field for it:
use App\Repositories\MongoDB\ProductRepository;
protected $productRepository;
public function __construct(
ProductRepository $productRepository,
) {
$this->productRepository = $productRepository;
}
public function updateProductOn()
{
$product = $this->productRepository->getModel()::where('_id', '=', '61e93a99667ad949974948fb')->first();
if ($product) {
$product->listProduct[0]['childProduct'][0]['productOn'] = strtotime('now');
$product->save();
}
}
And when I run that function, and save it, it gets the following error:
"message": "Indirect modification of overloaded property App\\Models\\Mongo\\Product::$listProduct has no effect",
"exception": "ErrorException",
I have researched and learned how to product->push and I have followed it, but it still doesn't work.And I also know push to save an array.
$product->push("listProduct[0].childProduct[0].productOn", strtotime('now'));
or
$product->push("listProduct[0]['childProduct'][0]['productOn']", strtotime('now'));
Is there any way to update productOn, please give me any suggestions. Thanks.
Related
I am doing update function to mongoDB in laravel. And I get some errors like this.
For example I have 1 table in mongoBD which is products:
{
"_id" : ObjectId("5e3a80d6d50c7d6f1a15b582"),
"status" : 1,
"name" : "Product 1",
"slug" : "product-1",
"description": 'test product 1',
"createdAt" : 1658905822,
"updatedAt" : 1659407411
}
In controller :
use App\Models\Product;
public function update(Request $request)
{
$reqProduct = $request->data;
// dd($reqProduct) result :
// array(65) {
// ["_id"]=>
// string(24) "5e3a80d6d50c7d6f1a15b582"
// ["status"]=>
// int(1) 1
// ["name"]=>
// string(11) "Product 1"
// ["slug"]=>
// string(11) "product-1"
// ["description"]=>
// string(5) "sss"
// ["createdAt"]=>
// string(10) "1658905822"
// ["updatedAt"]=>
// string(10) "1678537691"
// }
$product = Product::where('_id', '=', $reqProduct['_id'])->first();
$product->update($reqProduct);
}
So the update was successful. But my database sometimes come up with a case, updatedAt when saving in int type, but sometimes it is stored in date type (ISODate).
Example :
{
"_id" : ObjectId("5e3a80d6d50c7d6f1a15b582"),
"status" : 1,
"name" : "Product 1",
"slug" : "product-1",
"description": 'test product 1',
"createdAt" : 1658905822,
"updatedAt" : ISODate("2013-10-01T00:00:00.000Z")
}
And when I click update the error message: Object of class Carbon\\Carbon could not be converted to int.
I tried :
$product = Product::where('_id', '=', $reqProduct['_id'])->first();
$product->unset('updatedAt', $product->updatedAt);
$product->update($reqProduct);
But can't. Everyone please give me the solution so I can fix it, Thanks.
Simply convert it to datetime string before updating.
$updated_at = Carbon::createFromTimestamp(1678537691)->toDateTimeString();
["updatedAt"] => $updated_at,
I got the data json from API and I want to store them to my database.
data json sample :
{
"success": true,
"data": [
{
"status_employee_id": "1",
"name": "Manager"
},
{
"status_employee_id": "2",
"name": "Staff"
},
{
"status_employee_id": "3",
"name": "OB"
},
{
"status_employee_id": "4",
"name": "Fired"
},
{
"status_employee_id": "5",
"name": "Retired"
}
]
}
My model
class StatusEmployee extends Model
{
use HasFactory;
protected $table = 'status_employee';
protected $fillable = [
'status_employee_id','name'
];
public $timestamps = false;
}
I have tried use this in my controller
public function store()
{
$client = new \GuzzleHttp\Client();
$res = $client->request('GET', 'http://xx.xx.xx.xx/tools/public/get_status_employee');
$datas = json_decode($res->getBody(), true);
foreach($datas as $data){
StatusEmployee::create([
'status_employee_id' => $data->status_employee_id,
'name' => $data->name,
]);
}
}
And I want to store the data json sample to my table status_employee. How to make it?
It's easy, Laravel Eloquent will do everything for you.
// If json is in string decode first
$data = json_decode($res->getBody(), true); // to array
// Eloquent approach
StatusEmployee::insert(#$data['data']);
I assume you use Laravel since you have mentioned Laravel in your tags.
DB::table('status_employee')->insert(json_decode($res->getBody(),true)['data']);
{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 }
{ "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 }
{ "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
{ "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 }
{ "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
Above is a 'books' table
Using LARAVEL framework and Eloquent ORM model, how to return the following result:
{ "author" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "author" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
I am learning Laravel.
You could use GROUP_CONCAT.
Book::groupBy('author')
->select(DB::raw('GROUP_CONCAT(title) as books'), 'author')
->get()
->map(function ($author) {
$author->books = preg_split('/,/', $author->books);
return $author;
});
This will get you:
{ "author" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "author" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
If the table structure is within your control, then the better solution would be to place the data into two tables books and authors, to avoid data duplication as is the case now with a single table.
Then define two Eloquent Models and setup a one-to-many relationship. As in one author can have many books written.
So the Book model might look like this:
class Book extends Model
{
public function author()
{
return $this->belongsTo(Author::class);
}
}
And the Author model might look like this:
class Author extends Model
{
public function books()
{
return $this->hasMany(Book::class);
}
}
Now you can use the relationship, eager loading and a little collection processing to fetch the data in your preferred format:
$authors = Author::with('books')->get()->map(function ($author) {
return [
'author' => $author->name,
'books' => $author->books->pluck('title')
];
});
You might also want to read up on Database Normalization, and in your case more specifically The 1st Normal Form.
I'm trying to create a record from the parent relationship.
My models
use Illuminate\Database\Eloquent\Model;
class Cheque extends Model
{
protected $fillable = [
"numero",
"banco",
"factura_id",
];
public function factura()
{
return $this->belongsTo('App\Factura');
}
}
class Factura extends Model
{
protected $fillable = [
'cliente_id',
'cotizacion_id',
'sub_total',
'porcentaje_descuento',
'descuento_total',
'total',
'iva',
];
public function cheque()
{
return $this->hasMany('App\Cheque');
}
This is my code in FacturaController
$factura = Factura::create($request->all());
$factura->cheque()->create($request->cheque);
The request:
{
"cliente_id" : "3",
"nombre" : "gustavo",
"sub_total" : 20000.50,
"porcentaje_descuento" : 20,
"descuento_total" : 50,
"total" : 100,
"iva" : 12,
"cheque" : {
"1" : {
"numero" : "25525886",
"banco" : "banesco"
}
}
}
The 'cheque' is created but the fields 'numero' and 'banco' are left blank.
What am I doing wrong?
Thanks in advance
$factura->cheque($factura_id)->create($request->cheque);
Try this.
$factura = Factura::create($request->all());
$cheque = Cheque::create($request->only(['input', 'inputenter code here']);
$cheque = factura_id = $factura-id;
$cheque->save();
it's something like this
I would like to know if I do the things correctly.
Let's say I have a table "countries". To get only some fields of this table, in a certain order, I have this url :
/countries?fields=id,country_name&desc=country_name
And the result is clear:
[
{
"id": "SP",
"country_name": "Spain"
},
{
"id": "IT",
"country_name": "Italy"
},
{
"id": "FR",
"country_name": "France"
},
{
"id": "CN",
"country_name": "China"
} ]
To do that I have this route :
Route::get('/countries', 'CountryController#index');
And the method index is :
public function index(Request $request)
{
$query = Country::query();
if ($request->has('fields')){
$fields = explode(',', $request->input('fields') );
foreach ($fields as $field) {
$query->addSelect($field);
}
}
if ($request->has('sort')){
$query->orderBy($request->input('sort'));
}
if ($request->has('desc')){
$query->orderBy($request->input('desc'), 'desc');
}
$countries = $query->get();
return response()->json($countries, 200);
}
It works fine.
My question is am I doing the things correctly ? Is there any other methods ?
To prevent unknown column exception try this:
import Schema class use Illuminate\Support\Facades\Schema;
add this:
$table = "countries";
if ($request->has('fields')){
$fields = explode(',', $request->input('fields') );
foreach ($fields as $field) {
if(!Schema::hasColumn($table,$field)){
return response("Unknown field", 422);
}
$query->addSelect($field);
}
}
What you are doing to me has no vulnerability in it and is very optimized too.
You can try using this:
$countries = $query->pluck('id', 'country_name');
Please check and let me know.