When use create() the fillable values come null - laravel

i have an array with values that i am trying to insert it in the database, but when i use create() the values are inserted as null in database while if i use insert() the values insert correct.
This is the code from the controller
public function store(Request $request)
{
$request->validate([
'order_number' => 'required',
'client' => 'required',
'products' => 'required',
'amount' => 'required',
'description' => 'required',
]);
for($i = 0; $i < count($request->products); $i++)
{
$values[] = [
'order_number' => $request->order_number,
'client' => $request->client,
'products' => $request->products[$i],
'amount' => $request->amount[$i],
'description' => $request->description
];
}
Order::create($values);
return redirect('/')->with('msg', 'Order Saved successfully!');
}
and this is the code from the model
public $timestamps = true;
protected $fillable = [
'order_number',
'client',
'products',
'amount',
'description',
];
The names are the same and in the database, any reason why the values come null when i use create() method?

insert() method accepts multiple objects in form of arrays to be created, for example :
DB::table('users')->insert([
['email' => 'picard#example.com', 'votes' => 0],
['email' => 'janeway#example.com', 'votes' => 0],
]);
But create() method does not accept such structure. You cannot create multiple entries using this method. So in this case you either keep using insert(), either move your create() inside for loop.
Edit : createMany() works only on relationships, and apparently DB manipulation in loops is antipattern. In that case you can do something like this :
$created_at = now();
for($i = 0; $i < count($request->products); $i++)
{
$values[] = [
'order_number' => $request->order_number,
'client' => $request->client,
'products' => $request->products[$i],
'amount' => $request->amount[$i],
'description' => $request->description,
'created_at' => $created_at,
'updated_at' => $created_at,
];
}
Order::insert($values);

Related

How to get from request->value one value at a time inside foreach loop

Hello i have this code in laravel controller and i get an error for a single value:
public function store(Request $request)
{
$values = [];
$request->validate([
'order_number' => 'required',
'client_id' => 'required|exists:clients,id',
'description' => 'required',
'products' => 'required|exists:products,id',
'amount' => 'required',
]);
$order = Order::create($request->all());
foreach ($request->products as $product) {
$values[] = [
'order_id' => $order->id,
'product_id' => $product,
'amount' => $request->amount,
];
$amount = Product::find($product);
$total_value = $request->amount + $amount->amount; //the error happens here
$amount->update(['amount' => $total_value]);
}
$order->products()->attach($values);
return redirect('/')->with('msg', 'Order Saved successfully!');
}
All the values come except the $request->amount that comes as array and not as a single value in a row. This is the error i get:
Unsupported operand types: array + string
This is the product model:
protected $fillable = [
'name',
'price',
'amount',
];
public function orders()
{
return $this->belongsToMany(Order::class);
}
And this is dd($request->amount);
Assuming that $request->amount is directly related to $request->products with the index then you would either need to combine products and amount before you send the request or iterate over products with the index.
foreach ($request->products as $index => $product) {
$values[] = [
'order_id' => $order->id,
'product_id' => $product,
'amount' => $request->amount[$index], //Reference via index
];
$amount = Product::find($product);
$total_value = $request->amount[$index] + $amount->amount; //Also here
}
}

How to use sync eloquent method

Hello i am trying to make a code that updates existing values by removing existing ones/add new ones or make changes in the existing values. This is the code i have done so far:
public function update(Request $request, $id)
{
$order = Order::find($id);
$request->validate([
'order_number' => 'required',
'client_id' => 'required',
'description' => 'required',
'productOrder' => 'required',
'productOrder.*.product_id' => 'required|distinct|exists:products,id',
'productOrder.*.amount' => 'required|numeric|min:1',
]);
$order->update($request->all());
foreach ($request->productOrder as $product) {
$values[] = [
'order_id' => $order->id,
'product_id' => $product['product_id'],
'amount' => $product['amount'],
];
$amount = Product::find($product['product_id']);
$totalValue = $product['amount'] + $amount->amount;
$amount->update(['amount' => $totalValue]);
// $order->products()->sync([$product['product_id'] => array(
// 'product_id' => $product['product_id'],
// 'amount' => $product['amount'], THIS CODE MAKES ERROR BY DELETING ALL THE VALUES EXCEPT ONE
// )]);
}
$order->products()->detach();
$order->products()->attach($values); //I WANT THE CODE TO DO THIS FUNCTIONS BASICALLY
$orders = Order::all();
$orders->load('client', 'products');
return view('orders/index', compact('orders'));
}
I think you should use this
$values = [];
foreach ($request->productOrder as $product) {
/* This is the sync id && This is the pivot column */
$values[$product['product_id']] = ['amount' => $product['amount']];
$amount = Product::find($product['product_id']);
$totalValue = $product['amount'] + $amount->amount;
$amount->update(['amount' => $totalValue]);
}
// $values keys must be a product_id and its value must be pivot values
$order->products()->sync($values);

How to use createMany

I am new to Laravel and I have many arrays that I want to insert in database with createMany() this is my code what I have done so far:
public function store(Request $request)
{
$request->validate([
'order_number' => 'required',
'client' => 'required',
'products' => 'required',
'amount' => 'required',
'description' => 'required',
]);
for($i = 0; $i < count($request->products); $i++)
{
$values[] = [
'order_number' => $request->order_number,
'client' => $request->client,
'products' => $request->products[$i],
'amount' => $request->amount[$i],
'description' => $request->description,
];
}
dd($values);
Order::createMany($values);
return redirect('/')->with('msg', 'Order Saved successfully!');
}
I saw on Internet and documentation examples like this:
createMany on createMany in Laravel?
Documentation
But I don't understand how it works.
This is how the values show up:
createMany() only works on relationships, what you should be using is insert()
So Order::insert($values);
You can read more on insert here: https://laravel.com/docs/9.x/queries#insert-statements
Because you want the timestamps to be updated then what you can do is this:
foreach($values as $value){
Order::create($value);
}
Since you are modifying the array before creating, you can always just add the updated_at and created_at
$values[] = [
'order_number' => $request->order_number,
'client' => $request->client,
'products' => $request->products[$i],
'amount' => $request->amount[$i],
'description' => $request->description,
'updated_at' => now(),
'created_at' => now(),
];
If you using Laravel 8+ try to use upsert
Order::upsert($values,'order_number');

how to update key/value database with laravel?

I'm just learning laravel. I want update key / value in database with laravel api but not work.
My products model is one to many with ProductMeta and many to many with contents model.
My Models
class Product extends Model
{
use HasFactory;
protected $guarded = [];
public function productMeta()
{
return $this->hasMany(ProductMeta::class);
}
public function content()
{
return $this->belongsToMany(Content::class, 'product_contents')->withTimestamps();
}
}
class ProductMeta extends Model
{
use HasFactory;
protected $guarded = [];
public function products()
{
return $this->belongsTo(Product::class);
}
}
class Content extends Model
{
use HasFactory;
protected $guarded= [];
public function product()
{
return $this->belongsToMany(Product::class, 'product_contents');
}
Controller
public function update(Request $request, $id)
{
$product = Product::findOrFail($id);
DB::table('product_metas')
->upsert(
[
[
'product_id' => $product->id,
'key' => 'name',
'value' => $request->name,
],
[
'product_id' => $product->id,
'key' => 'price',
'value' => $request->name,
],
[
'product_id' => $product->id,
'key' => 'amount',
'value' => $request->name,
],
],
['product_id','key'],
['value']
);
return \response()->json([], 204);
}
Table Structure
API parameter
I tried with update and updateOrcreate and updateOrInsert and upsert methods.
just in upsert method writed database but inserted new data.not updated.
In your case, you should use updateOrCreate() instead of upsert.
Product::updateOrCreate([
'product_id' => $id,
'name' => $request->name,
'price' => $request->price,
'amount' => $request->amount
]);
or
Product::upsert([
[
'product_id' => $id,
'name' => $request->name,
'price' => $request->price,
'amount' => $request->amount
]
], ['product_id'], ['name', 'price', 'amount']);
In addition your problem is your table name is not matching with your structure table name. In your controller DB::table('product_metas') should be DB::table('products_meta').
my problem solved this way:
ProductMeta::query()->where('product_id', $id)->upsert([
['product_id' => $id, 'key' => 'name', 'value' => $request->name],
['product_id' => $id, 'key' => 'price', 'value' => $request->price],
['product_id' => $id, 'key' => 'amount', 'value' => $request->amount]],
['product_id'], ['value']);
$contentRecord = Product::find($id);
$contentRecord->content()->update(['path'=>$request->path]);
return response()->json([], 204);
I forget use query() method for ProductMeta and added $table->unique(['product_id', 'key']); to product meta migration.
**products relation one to many with product Meta
And Many to many with content.

laravel validatetor in controller seems not working

The validate() function from my sales controller seems not working, I am comparing it to my other controller, it looks like it should work but it is not. it looks like the validate() is being bypassed. here's my controller
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class SalesController extends Controller
{
public function store(Request $request)
{
$this->validate($request, [
'user_id' => 'required',
'status_id' => 'required',
'currency_id' => 'required',
'company_id' => 'required',
'invoice_no' => 'nullable',
'notes' => 'nullable',
'admin_notes' => 'nullable',
'due_date' => 'nullable',
'publish' => 'nullable',
'product_id' => 'required|min:1',
'product_code' => 'required|min:1',
'product_name' => 'required|min:1',
'quantity' => 'required'
]);
$sales = $request->only(
'user_id',
'status_id',
'currency_id',
'currency_rate',
'due_date',
'company_id',
'invoice_no',
'notes',
'admin_notes',
'delivery_date',
'publish'
);
$sales['grandtotal'] = (float) str_replace(',', '', $request->grandtotal);
$sales['grandtotalcost'] = (float) str_replace(',', '', $request->grandtotalcost);
$sales = Sales::create($sales);
$input = $request->all();
for($i=0; $i<= count($input['quantity']); $i++) {
if(empty($input['quantity'][$i]) || !is_numeric($input['quantity'][$i])) continue;
$items = [
'sales_id' => $sales->id,
'product_id' => $input['product_id'][$i],
'product_code' => $input['product_code'][$i],
'product_name' => $input['product_name'][$i],
'price' => $input['price'][$i],
'cost' => $input['cost'][$i],
'quantity' => intval($input['quantity'][$i]),
'total_price' => (float) str_replace(',', '', $input['total_price'][$i]),
'total_cost' => (float) str_replace(',', '', $input['total_cost'][$i]),
];
Salesitems::create($items);
}
// $ponumbers = Ponumbers::create($request->only('purchase_no'));
$invnum = $request->all();
$invnumbers = new Invnumbers;
$invnumbers->sales_num = $invnum['invoice_no'];
$invnumbers->save();
if ($request){
Session::flash('message','Invoice was successfully added');
Session::flash('m-class','alert-success');
} else {
Session::flash('message','Data is not saved');
Session::flash('m-class','alert-danger');
return redirect()->route('sales.index');
}
return redirect()->route('sales.index');
}
}
My Blade
<input class="form-control autocomplete_txt product_name" type='text' data-type="product_name" id='product_name_1' name='product_name[]' for="1" readonly/>
#if ($errors->has('product_name')) <p class="help-block">{{ $errors->first('product_name') }}</p> #endif
if I submit my form with product name, instead of throwing error from validate,
By seeing your code, to me it seems your product_id should be an array. So the validation should be:
'product_id' => 'array|required|min:1',
'product_id.*' => 'required',
instead of
'product_id' => 'required|min:1',
Try to use $request->validate([... instead of $this->validate($request, [.... I'm not sure is there validate in your controller...

Resources