How to resolve PHP Laravel Sql Insert error? - php

When I press the buy button I get this error
QueryException in Connection.php line 729:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'qty' cannot be null (SQL: insert into orders (user_id, product_id, qty, updated_at, created_at) values (3, 1, , 2018-10-06 20:44:27, 2018-10-06 20:44:27))
first of all, I'm a beginner so I'm still learning and I do not know if some of this is correct, all I want is when I press the buy button it will display the form and I will type the quantity then submit and my quantity will increase and the products inventory will decrease and if I deleted my order, The products will increase again (I did this and I think it will work) and the user can update his quantity and if someone ordered something the seller cannot delete it, only update his inventory as same as the buy button way and the form, and if the users ordered all products it will display (out of stock) with a dead link button, I am training, It is not homework and I do not know how to write all functions..
this is the Buy button
<li><span>Buy</span></li>
which should pop up the next form when I press it,
this is my form code for the buy button
<form method="POST" action="/add_order/{{ $product['id'] }}" class="klaviyo_subscription_form" enctype="multipart/form-data">
{{ csrf_field() }}
<input type="hidden" name="g" value="LIST_ID">
<div class="klaviyo_fieldset">
<p class="klaviyo_header">Please define quantity you need, then order it.</p>
</div>
<div class="klaviyo_fieldset">
<div class="klaviyo_field_group{{ $errors->has('qty') ? ' has-error' : '' }}">
<label for="k_id_modal_$email" style="display: block; text-align:center">Quantity</label>
<input type="number" id="k_id_modal_$email" name="qty" style="display: block; margin:auto">
#if ($errors->has('qty'))
<span class="help-block">
<strong>{{ $errors->first('qty') }}</strong>
</span>
#endif
</div>
</div>
<div class="klaviyo_fine_print"></div>
<div class="klaviyo_form_actions">
<button type="submit" class="klaviyo_submit_button">
<span>Order Now</span>
</button>
</div>
<div class="klaviyo_below_submit" ></div>
</form>
OrderController
public function store(Request $request, $id)
{
$product = Product::find($id);
$order = new Order();
$order->user_id = Auth::user()->id;
$order->product_id = $id;
$order->qty = $request->get('qty');
$product->inv = $product->inv - $order->qty;
$order->save();
$product->save();
return redirect('/');
}
thanks for reading :D

Request is object and not array! You need to use method to get request value. Check updated code
public function store(Request $request, $id)
{
$product = Product::find($id);
$order = new Order();
$order->user_id = Auth::user()->id;
$order->product_id = $id;
$order->qty = $request->get('qty');
$product->inv = $product->inv - $order->qty;
$order->save();
$product->save();
return redirect('/');
}
This will work if logic for passing "qty" to request is correct. You can do dump of request and die inside store function, to make sure about this fact.

Your Problem is you sending the data with the POST method.
But you access the data from the GET method.
OrderController
$order->qty = $request->get('qty'); // this is where you are wrong.
Change this either,
$order->qty = $request->post('qty');
or,
$order->qty = $request->qty // this is the preferred approach.

In your database table filed "qty" set default value null or as default 0.
and write
$order->qty = $request->qty;
it will work fine

Related

Laravel: How to get ID from Papers Table to Store in Bookmarks Table

I can't get the PaperID to store into my Bookmarks DB
here is my controller for the bookmark store function
public function store(Request $request)
{
$request->validate([
'BookmarkName' => 'required',
]);
$paper = DB::table('papers')
->where('PaperID', '=', $request->paper_id)
->value('PaperID');
$bm = new Bookmarks();
$bm->BookmarkName=$request->BookmarkName;
$bm->paper_id = $paper;
$bm->save();
return redirect()->back()->with('success','Bookmark Added');
}
here is the form to call the function
<form class="bookmarkInput" action="{{ route('Bookmarks')}} " method="POST" >
#csrf
<div class="group">
<input class="inputInfo" type="text" name="BookmarkName" required>
<span class="highlight"></span>
<span class="bar"></span>
<label class="infoLabel">Bookmark Name</label>
</div>
<br>
<br>
<button class="redBtn" type="submit">Add</button>
</form>
here is the route for it
Route::post('/Bookmarked', [App\Http\Controllers\BookmarkController::class, 'store'])->name('Bookmarks');
I do not know why it isn't getting the ID calling papers DB seems good but it doesn't want to get the current ID of the paper I want to bookmark
You are not passing paper_id from form.
That's why your ->where('PaperID', '=', $request->paper_id)
don't have value of paper_id.
you can pass paper_id from form by using hidden input field.
<input type="hidden" name="paper_id" value = {{ $paper_id }}>
Remember to pass paper_id variable containg paper_id value to the blade having form.
Also add ->first() before ->value('PaperID').

Laravel search only exact match

Newbie to PHP/Laravel here.
Expected behavior
I want to use a form action to get data from database by inserting the id, something like the couriers tracking id. Until now it is working, but i want to show the results only if that id exist on the database
Code
Controller
public function search(Request $request)
{
$request->validate([
'query' => 'required|min:10|max:10',
]);
$query = $request->input('id');
$orders = Order::where('id','LIKE',"%$query%")->get();
$name = $request->input('id', '$id');
return view('order-details', compact('orders'));
order.blade
<form action="{{ route('order-details') }}" method="GET" class="order-form">
<div class="row">
<div class="col-lg-12">
<input type="text" placeholder="Track Order ID" name="query" id="query" value="{{ request()->input('query') }}">
</div>
<div class="col-lg-12">
<button type="submit">Submit Now</button>
</div>
</div>
</form>
#if(count($errors) > 0)
<ul>
#foreach ($errors->all() as $error)
<li>{{$error}}</li>
#endforeach
</ul>
#endif
route
Route::get('order', 'OrderController#index')->name('order');
Route::get('order-detail', 'OrderController#search')->name('order-details');
I think your problem is you are using a like condition, like is notoriusly flakey on numbers.
$query = $request->input('id') ?? -1;
Order::where('id', $query)->get();
Where on only id, will only returns rows where id exists.
You are using a wrong query.
$orders = Order::where('id','LIKE',"%$query%")->get();
The like operator will get anything like that query and not only.
You just need to remove the like operator to get only orders that match the exact id.
$orders = Order::where('id',$query)->get();
You can also add the exists rule:
The field under validation must exist on a given database table.
$request->validate([
'query' => 'exists:orders,id',
]);

Laravel 5.1 Creating default object from empty value

I am using Laravel 5.1 PHP framework. When I try to update my record, I get the error:
"ErrorException in AdminController.php line 108: Creating default
object from empty value".
I have searched in google but I can't find any results to solve my problem.
Routes
Route::get('/admin/no', 'AdminController#index');
Route::get('/admin/product/destroy/{id}', 'AdminController#destroy');
Route::get('/admin/new', 'AdminController#newProduct');
Route::post('/admin/product/save', 'AdminController#add');
Route::get('/admin/{id}/edit', 'AdminController#edit');
Route::patch('/admin/product/update/{id}', 'AdminController#update')
AdminController
public function edit($id)
{
$product = Product::find($id);
return view('admin.edit', compact('product'));
}
public function update(Request $request, $id)
{
$product = Product::find($id);
$product->id = Request::input('id');
$product->name = Request::input('name');
$product->description = Request::input('description');
$product->price = Request::input('price');
$product->imageurl = Request::input('imageurl');
$product->save();
//return redirect('/admin/nο');
}
enter code here
edit.blade.php
div class="panel panel-info">
<div class="panel-heading">
<div class="panel-title">Edit Product</div>
</div>
<div class="panel-body" >
<form action="/admin/product/update/{id}" method="POST"><input type="hidden" name="_method" value="PATCH"> <input type="hidden" name="_token" value="{{ csrf_token() }}">
enter code here
The problem is that $product = Product::find($id); returns NULL. Add the check:
if(!is_null($product) {
//redirect or show an error message
}
Though this is your update method, so probably you're having an error while building the url for this method. It might be a wrong id you're passing to this route.
Your form action has an error:
<form action="/admin/product/update/{id}" method="POST">
Notice the curly braces, Blade's syntax is {{ expression }}, not just {}. So id is never passed to the product.update route. Just change it to:
<form action="/admin/product/update/{{$id}}" method="POST">
check if the product exists then do the update
The form will look like this
<form action="/admin/product/update/{{$id}}" method="POST">
$ sign was missing :)
For update entity in laravel uses PUT method not POST. update form method and try.
<form action="/admin/product/update/{id}">
<input name="_method" type="hidden" value="PUT">
Check your web.php file maybe mistake your controller name.
This may be helpful for similar issues for others..
Instead of $product = Product::find($id); use $product = Product::where('some_other_id', $id);. I am saying this because you might be giving reference to some_other_id like a foreign key instead of primary key.

inserting array value to database laravel

I have a form attributes called, name, description and features where features is a multiple checkboxes which is like
feature 1
feature 2
feature 2
feature 4
User can select multiple checkbox at once. I have a database table called product like
-----------------------------------------
id name description features
-----------------------------------------
When user selects the multiple checkbox, i need to insert all checkbox value in the features column. Right now I can echo the selected checkbox value like
$feat = Input::get('features');
foreach ($feat as $key => $n){
echo $feat[$n];
}
but I need those features to insert into the database, for normal insertion, we would do like:
$product = new Product;
$product->name = Input::get('name');
$product->description = Input::get('description');
$product->features = Input::get('features');
$product->save();
but how should i modify the above code in order to save the array value to the database? I am trying to insert the value to same column because i won't be querying it on the basis of features.
It's quite simple. If you know that you won't query the features, it's perfectly fine to store them as Json or a serialized array. But if you will need to query them and they are a key aspect of your application, you should put them in their own table.
I prefer to store arrays in Json-format because it's easier to read and is not specific to PHP. Laravel gives you pretty sweet options to make this work.
At first, declare the features-field of you products-table as json in your migration:
Schema::create('products', function (Blueprint $table) {
// ...
$table->json('features');
});
Then tell your Product-model to automatically cast it to an array when you access it by simply setting a $casts-attribute:
class Product extends Model
{
// ...
protected $casts = [
'features' => 'json'
];
}
That's it. Now the array will be stored as Json, but when you access it with $product->features you'll get an array back.
To make everything even more simple, you should set up a fillable attribute on your Product model:
class Product extends Model
{
// ...
protected $fillable = ['name', 'description', 'features'];
}
This allows for doing something like this in your controller (or wherever you create the product):
$product = Product::create(Input::all());
...instead of newing it up and setting the attributes one by one.
And as mentioned above, be sure you don't need the features to be query-able, meaning you won't encounter situation where you're trying to get certain products only having specific features or something. But if you do need to look up features, you should put them in their own table. Otherwise this approach is just fine because it's more convenient.
Please look to database normalization for information how to store Data which is in a 1:N relationship. You have to create an extra table like "product_feature" with the attributes: ['id', 'product_id', 'function_name'].
Then your Insert function looks like this:
$product = new Product;
$product->name = Input::get('name');
$product->description = Input::get('description');
$product->save();
$feat = Input::get('features');
foreach ($feat as $key => $n){
$product_function = new ProductFunction;
$product_function->product_id = $product->id;
$product_function->function_name = $feat[$n];
$product_function->save();
}
Hope it helps!
You could use the json_encode function to save the array as a json string.
$product->features = json_encode(Input::get('features'));
But I will also agree with #AdrianBR it is a bad idea to saving the array value to the database in a single column.
I had something similar to this although i used ajax to send the values
<div class="row mb-3" id="insert_new_item">
<div class="col-lg-6">
<p>Item Description</p>
<input value="" type="text" name="order[description]" class="form-control product " id="" placeholder="Your Item Description">
</div>
<div class="col-lg-1 col-sm-6 col-12 mt-lg-0 mt-3">
<p>Qty</p>
<input placeholder="0" type="text" name="order[quantity]" min="1" class="text-right form-control qty" id="" min="1">
</div>
<div class="col-lg-2 col-sm-6 col-12 mt-lg-0 mt-3">
<p>Rate/Unit (₦ )</p>
<input placeholder="0.00" type="text" name="order[rate]" class="text-right form-control rate" id="">
</div>
<div class="col-lg-2 mt-lg-0 mt-3">
<p>Amount (₦ )</p>
<input type="text" name="order[amount]" id="" class="text-right form-control amount" readonly value="0" >
</div>
<div class="col-lg-1">
<span><i class="fa fa-times text-danger removeItem" style="font-size: 22px"></i></span>
</div>
So when i console.log(any value) i get this:
["0" : "value 1", "1" : "value 2"]
from my controller i can do this
foreach ($request->description as $key => $description) {
$order = Order::create([
'description' => $description,
'amount' => $request->rate[$key],
'quantity' => $request->quantity[$key],
'invoice_id' => 7
]);
}
You can insert like this,
$candidate_data = array(
'mobile' => $request->get('mobile'),
'password' => $request->get('password')
);
DB::('tablename')->insert($candidate_data);

Laravel: Getting the Value of a Field In a Table

What I'm trying to do is get the available credits from the users table and 'credits' field and get the price of the current item in the foreach loop which is the 'normalprice' field in the 'items' table.
When a user fills in the amount he wants to put toward the 'normalprice' of an item, i want to subtract from the number in his 'credits' field, and create a new variable for 'This is the price of the item after you've put credits toward it' and display it.
The users table and items table are on a many-to-many relationship, and i've been able to display a user item by doing
$user->item
What i've done is bellow is wrong, because 'normalprice' in '$item->normalprice;' is not a property. I'm trying to find out how I can make $itemprice equal the value of 'normalprice' in the current #foreach ($user->items as $item)
Controller:
public function allocateCredit(){
$validator = Validator::make(Input::all(),
array(
'puttoward' => 'Integer',
));
$user = Auth::user();
$items = Item::all();
$userItems = Auth::user()->items;
$itemprice = $item->normalprice;
$available = $user->credits;
$goodtogo = ($available > $itemprice) ? TRUE : FALSE;
if($goodtogo === true){
$howmuch = Input::get('puttoward');
$newavailable = $howmuch - $available;
$itembalance = $itemprice - $howmuch;
$user->credits = $newavailable;
}
if($user->save()){
return Redirect::route('account')->with('global', 'Success.');
}
}
View:
#foreach ($user->items as $item)
<div class="sep">
<div class="nameIt">
{{ $item->name }}
<form action="{{ URL::route('allocate-credits-post') }}" method="post" role="form">
<div class="form-group">
<label for="exampleInputPassword1">Allocate credits</label>
<input type="intiger" class="form-control" name="puttoward" placeholder="$0.00">
</div>
<button type="submit" class="btn btn-default">Submit</button>
{{ Form::token() }}
</form>
Since you're using a form submission to call your Controller, why don't you populate the $item->normalprice into the form as hidden type like:
<input type="hidden" name="NormalPrice" value="{{$item->normalprice}}">
Then access the value in your controller with Input::get('NormalPrice')
or if that is not desired for security reason, then you can populate the $item->id instead and find out the price for that ID in your controller.

Categories