laravel-5.7: SQLSTATE[HY000]: General error: 1364 Field 'category_id' doesn't have a default value - laravel

I'm new to Laravel and trying to add Product under Category but when I add Product then it shows this error:
SQLSTATE[HY000]: General error: 1364 Field 'category_id' doesn't have a default value (SQL: insert into products ..."
Initially i was adding these products without under any category than it was working and now its not adding under Category.
can anyone would prefer to provide me its solution?
here is my form:
<form enctype="multipart/form-data" class="form-horizontal" method="post" action="{{ url('admin/add-product') }}" name="add_product" id="add_product" novalidate="novalidate">{{ csrf_field() }}
<div class="control-group">
<label class="control-label">Under Category</label>
<div class="controls">
<select name="category_id" id="category_id" style="width:220px;">
<?php echo $categories_drop_down; ?>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label">Product Name</label>
<div class="controls">
<input type="text" name="product_name" id="product_name">
</div>
</div>
<div class="uploader" id="uniform-undefined"><input name="image" id="image" type="file" size="19" style="opacity: 0;"><span class="filename">No file selected</span><span class="action">Choose File</span></div>
div class="form-actions">
<input type="submit" value="Add Product" class="btn btn-success">
</div>
</form>
here is ProductsController:
ProductsController.php
public function addProduct(Request $request)
{
if ($request->isMethod('post'))
{
$data = $request->all();
$product = new Product;
$product->product_name = $data['product_name'];
$product->product_code = $data['product_code'];
$product->product_color = $data['product_color'];
if ( ! empty($data['description']))
{
$product->description = $data['description'];
}
else
{
$product->description = '';
}
$product->price = $data['price'];
// Upload Image
if ($request->hasFile('image'))
{
$image_tmp = Input::file('image');
if ($image_tmp->isValid())
{
$extension = $image_tmp->getClientOriginalExtension();
$filename = rand(111, 99999) . '.' . $extension;
$large_image_path = 'images/backend_images/products/large/' . $filename;
$medium_image_path = 'images/backend_images/products/medium/' . $filename;
$small_image_path = 'images/backend_images/products/small/' . $filename;
// Resize Images
Image::make($image_tmp)->save($large_image_path);
Image::make($image_tmp)->resize(600, 600)->save($medium_image_path);
Image::make($image_tmp)->resize(300, 300)->save($small_image_path);
// Store image name in products table
$product->image = $filename;
}
}
$product->save();
/*return redirect()->back()->with('flash_message_success','Product has been added successfully!');*/
return redirect('/admin/view-products')->with('flash_message_success', 'Product has been added successfully!');
}
$categories = Category::where(['parent_id' => 0])->get();
$categories_drop_down = "<option value='' selected disabled>Select</option>";
foreach ($categories as $cat)
{
$categories_drop_down .= "<option value='" . $cat->id . "'>" . $cat->name . "</option>";
$sub_categories = Category::where(['parent_id' => $cat->id])->get();
foreach ($sub_categories as $sub_cat)
{
$categories_drop_down .= "<option value='" . $sub_cat->id . "'> -- " . $sub_cat->name . "</option>";
}
}
return view('admin.products.add_product')->with(compact('categories_drop_down'));
}

Although, there would be better ways to write this problem, the immediate solution would be to set the category_id field of your Product.
$product->product_name = $data['product_name'];
$product->product_code = $data['product_code'];
$product->product_color = $data['product_color'];
// Add this:
$product->category_id = $data['category_id'];

The main problem you have here is that in your migration you have category_id is not nullable which means it should have a value assigned to it from the controller you can either assign a value for it from your controller or you can go to your migration file and add this line
$table->integer('catagory_id')->nullable();
Then you will remigrate the table and it shouldn't throw this error again, but I prefer that you assign a value for it if you have relationship or something you want to connect it to it but if you don't have relationships then the entire category_id is useless in my point of view
If you want to assign a value to it, you should do something like this in your controller after the new product line:
$product->category_id = $request->input('category_id');
because your controller didn't take the value of the input which has the name of
category_id

As the error implies, it does not have a default value, you could solve it by either create a migration (or revise the one you had) so the column 'category_id' is nullable or just add the following line in the product creation:
$product->category_id = NULL;
You may find more information if needed about nullable at Laravel migration documentation

Related

SQLSTATE[23000]: Integrity constraint violation: 4025 CONSTRAINT `notes.file` failed for `classroom`.`notes` (SQL: insert into `notes`

I am getting this error in laravel 8
SQLSTATE[23000]: Integrity constraint violation: 4025 CONSTRAINT notes.file failed for classroom.notes (SQL: insert into notes (classroom_id, user_id, title, description, file, status, code, updated_at, created_at) values (3, 3, tes, teset, G:\xampp\tmp\php87A.tmp|G:\xampp\tmp\php87B.tmp|G:\xampp\tmp\php88B.tmp|G:\xampp\tmp\php88C.tmp|notes/270584134_3084881908463864_7790143535087104689_n.jpg_d645920e395fedad7bbbed0eca3fe2e0.jpg|notes/271593123_1376415469456519_8005701171651680985_n.jpg_812b4ba287f5ee0bc9d43bbf5bbe87fb.jpg|notes/272092182_232722372382525_5526411493206144373_n.jpg_f457c545a9ded88f18ecee47145a72c0.jpg|notes/AAYUAQR3AAgAAQAAAAAAADzjqItE3P0yRQGwRg-HnEHXKQ.png_f457c545a9ded88f18ecee47145a72c0.png, 1, ZkF7yZhckH, 2022-02-16 09:40:08, 2022-02-16 09:40:08))
This is the form
<form method="POST" action="{{url('class/note/')}}" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="input-field">
<textarea id="title" name="title" class=" #error('title') is-invalid #enderror materialize-textarea validate"></textarea>
<label for="title">Note title</label>
</div>
<div class="input-field">
<textarea id="desc" name="description" class=" #error('desc') is-invalid #enderror materialize-textarea validate"></textarea>
<label for="desc">Note description</label>
</div>
<div class="input-field">
<p>Attach Files *</p>
<input type="file" class="filepond"
name="files[]" multiple />
</div>
<div class="input-field pb-5">
<input type="hidden" name="cid" value="{{ $classroom->id }}">
<button onclick="submitBtn()" id="working" class="btn waves-effect waves-light comment right" type="submit" name="action">Submit
<i class="material-icons right">send</i>
</button>
<script>
function submitBtn() {
document.getElementById('working').innerText = 'Please wait...';
};
</script>
</form>
This is the controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\Models\classroom;
use App\Models\post;
use App\Models\comment;
use App\Models\note;
use Auth;
class noteController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
public function store(Request $request)
{
$this->validate($request,[
'files' => 'required',
]);
$note = new note;
$user = Auth::user();
$randoml = Str::random(10);
$note->classroom_id = $request->input('cid');
$note->user_id = $user->id;
$note->title = $request->input('title');
$note->description = $request->input('description');
$files = array();
if($files = $request->file('files')){
foreach($files as $file){
$filename = $file->getClientOriginalname().'_' . md5(rand(10, 100)) .'.'. $file->getClientOriginalExtension();
$path = 'notes/';
$url = $path.$filename;
$file->move($path, $filename);
$files[] = $url;
$note->file = implode('|', $files);
}
}
$note->status = 1;
$note->code = $randoml;
$note->save();
return redirect()->back()->with('success', 'Note posted');
}
}
i think your file name length more than database column's valid length
You are trying to store file on every iteration. you should store the paths in an array as you have done but only store the file after every iteration is performed and path is stored in your $files[] array but laravel has simple image upload api here you can check this

[Codeigniter]Multiple upload cant insert to database and not uploading to directory

How to upload multiple images with Codeigniter 4.x ?
I tried to loop the do_upload function in my model but it's not working, and I tried another code that I got from GitHub but still, none of it works.
This is my view:
<div class="section-body">
<h2 class="section-title">Entry Group Passanger</h2>
<div class="row">
<div class="col-md-12">
<form action="<?= base_url('passanger/addgroup') ?>" method="POST" enctype="multipart/form-data">
<?php for($i=1;$i<=$pax['pax'];$i++) : ?>
<h5>Passanger ke-<?= $i ?></h5>
<div class="form-row">
<div class="col-md-6">
<label for="fullname">Fullname</label>
<input type="text" class="form-control" name="name[]">
<?= form_error('name', '<small class="text-danger pl-3">', '</small>'); ?>
</div>
<div class="col-md-6">
<label for="gender">Gender</label>
<select class="form-control select2-input" name="gender">
<option>-- Select Gender --</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
<option value="Other">Other</option>
</select>
<?= form_error('gender', '<small class="text-danger pl-3">', '</small>'); ?>
</div>
</div>
<div class="form-row">
<div class="col-md-12 mb-4 mt-2">
<label for="">Upload Passport</label>
<input type="file" name="upload_passport[]" id="input-file-now" class="dropify" />
</div>
</div>
this is my model :
public function addGroup()
{
$user = $this->db->get_where('user', ['username' => $this->session->userdata('username')])->row_array();
$pax = $this->getPaxById();
date_default_timezone_set('Asia/Jakarta');
$upload_image = $_FILES['upload_passport[]']['name'];
if ($upload_image) {
$config['upload_path'] = './assets/img/uploads/passport';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = '2048';
$this->load->library('upload', $config);
for($i=0;$i<$pax['pax'];$i++) {
if ($this->upload->do_upload('upload_passport[$i]')) {
$new_image = $this->upload->data('file_name');
} else {
echo $this->upload->display_errors();
}
}
}
$name = $this->input->post("name[]");
$gender = $this->input->post("gender[]");
$birthdate = $this->input->post("birthdate[]");
$no_passport = $this->input->post("no_passport[]");
$expire_passport = $this->input->post("expire_passport[]");
$destination = $this->input->post("destination[]");
$date = $this->input->post("date[]");
$dp1 = "0";
$dp2 = "0";
$lunas = "0";
$type = "Group";
$status = "Not Complete";
$permission = "0";
$upload_passport = $new_image;
$upload_dp1 = "default.png";
$upload_dp2 = "default.png";
$date_created = date('d/m/Y H:i:s');
$data = [];
$jumlah = $pax['pax'];
for($x=0;$x<$jumlah;$x++) {
array_push($data, [
'name'=>$this->input->post("name[$x]"),
'id_user'=> $user['id_user'],
'gender'=>$this->input->post("gender[$x]"),
'birthdate'=>$this->input->post("birthdate[$x]"),
'no_passport'=> $this->input->post("no_passport[$x]"),
'expire_passport'=> $this->input->post("expire_passport[$x]"),
'destination'=> $this->input->post("destination[$x]"),
'date'=> $this->input->post("date[$x]"),
'dp1'=> $dp1,
'dp2'=> $dp2,
'lunas'=> $lunas,
'pax'=> $pax['pax'],
'type'=> $type,
'status'=> $status,
'permission'=> $permission,
'upload_passport'=> $new_image,
'upload_dp1'=> $upload_dp1,
'upload_dp2'=> $upload_dp2,
'date_created'=> $date_created
]);
var_dump($data); die;
}
$this->db->insert_batch("passanger", $data);
}
What I want to get is:
array('','','upload_image'), array('','','upload_image')
When insert it to database but when I do it the upload just gets output null and it's not even uploaded to my uploads directory. I would really appreciate it if you help me, I've been stuck on this for 3 days. Thank you.
for ($i=0; $i < sizeof($_FILES['image']['name']) ; $i++) {
$_FILES['file']['name'] = $_FILES['image']['name'][$i];
$_FILES['file']['type'] = $_FILES['image']['type'][$i];
$_FILES['file']['tmp_name'] = $_FILES['image']['tmp_name'[$i];
$_FILES['file']['error'] = $_FILES['image']['error'][$i];
$_FILES['file']['size'] = $_FILES['image']['size'][$i];
$config['upload_path'] = PRODUCT_IMAGE_UPLOAD_PATH;
$config['allowed_types'] = 'gif|jpg|png|jpeg';
$config['encrypt_name'] = TRUE;
$this->load->library('upload', $config);
if ($this->upload->do_upload('file')){
$images[] = $this->upload->data('file_name');
}else {
echo $this->upload->display_errors();
}
}
Try this in Codeigniter 4
in your controller add this
$image_model = new App\Models\Images(); // Your model name that is load your model
if($imagefiles = $this->request->getFiles())
{
foreach($imagefiles['uploadImages'] as $img)
{
if ($img->isValid() && ! $img->hasMoved())
{
$image_name = $img->getRandomName(); // This is applicable if you want to change the name of the images
if($image_model->save_images($image_name))
{
$img->move(WRITEPATH.'uploads/images/ads', $image_name); // WRITEPATH.'uploads/images/ads' is the part you wish to save you file to
}
}
}
}
In your Model e.g Image model i have a method call save_images()as this
use Codeigniter\Model
class Images extends Model{
public function save_images($image = '')
{
// We set the column 'name' to be allow for data entry into the db. note this is mandatory for now.
// hope it will change in feature. 'name' is the column in database table where you will save the image name
// this command the CI4 db to select only the image column in the database table
$this->allowedFields = ['name'];
return $this->db->table('images')->insert(['name' => $image]);
// echo $sql = $this->db->getLastQuery();
}
}
Then in your html file input, do this
<form action="" method="post" enctype="multipart/form-data">
<div class="form-group">
<input type="file" name="uploadImages[]" multiple>
</div>
</form>
I hope this will work for you

Upload multiple image for posts in laravel 5.5

I want to know how can I have multiple image in my posts?
Currently I have ImageController which I tried to get images and attach to post_id but the issue of that is if I use that method because I still didn't save my post there will be no id to be attached to images.
Any idea on that?
Please take a look for better understanding:
https://ibb.co/huC1Qw
blade:
<form action="upload" id="upload" enctype="multipart/form-data" method="post">
<div class="row">
<div class="col-md-6"><input type="file" class="form-control" name="files[]" multiple></div>
<div class="col-md-6"><input type="submit" class="btn btn-success" value="Upload now"></div>
</div>
</form>
controller:
public function upload(Request $request) {
$files = $request->file('file');
if (!empty($files)):
foreach($files as $file):
Storage::put($file->getClientOriginalName(), file_get_contents($file));
endforeach
endif;
return \response::json(array('success' => true));
}
route:
Route::post('/upload', 'ImageController#upload');
Approach 1.
Return $request->photos or put them in the session while you are not done yet with post submitting. After it was submitted assign references.
Approach 2.
First, save them in [temp] then move and assign to the post.
Approach 3.
Create a default record in your database, assign images to that record, get the record_id post_id and return to the form that post_id. Then just populate that post with your post_id.
Approach 4.
It is not the good choice to save images in the database, just save them as file and place de reference link in the database, or find them by the id of the folder that has the same id as your post, or beautify links to them ... definitely not by saving them to database. It is my opinion, everyone has to find his/her way for an easy living.
Try this :-
use App\ProductsPhoto; \\ add in top of controller
public function upload(Request $request) {
$product = Product::create($request->all());
if ($request->hasFile('files')) {
$files = $request->file('files');
foreach($files as $file){
$productsPhotos = new ProductsPhoto;
$filename = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
$fileName = str_random(5)."-".date('his')."-".str_random(3).".".$extension;
$destinationPath = 'images/ProductsPhotos'.'/';
$file->move($destinationPath, $fileName);
$productsPhotos->product_id = $product->id,
$productsPhotos->filename = $fileName;
$productsPhotos->save();
}
}
return 'Upload successful!';
}
Hope it helps!
For upload and display images
if you are using two tables.
upload.blade.php
<form method="post" action="{{ url('/uploads') }}" enctype="multipart/form-data">
<input type="file" id="file" name="files[]" class="inputfile" value="{{ old('arquivo') }}" multiple />
Controller
public function show() {
$images = DB::select('SELECT * FROM table1 INNER JOIN table2 on table1.id = table2.id_file');
return view('index')->with('images', $images);
}
public function upload(yourRequest $request) {
$images = model1::create($request->all());
foreach ($request->files as $file) {
$filename = $file->store('/uploads');
modelFiles::create([
'id_file' => $images->id,
'file' => $filename
]);
}
return redirect()->action('Controller#show')->withInput(Request::only('name'));
}
index.blade.php
#foreach($images as $i)
<div class="item {{ $loop->first ? 'active' : '' }}">
<img src="{{ asset("storage/$i->file") }}" alt="...">
</div>
#endforeach

Laravel checkbox implementation for updating database

I've been trying to make an attendance management system in Laravel.
In the attendance view,when a checkbox is checked ,the controller function is supposed to increment the appropriate database column.
I've been having some issues.Here's my code:
views:
<div class="container">
<!--<div class="row">-->
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Take Attendance</div>
<h4><center>Teacher: {{ auth()->user()->name}}</center></h4>
<div class="form-inline">
#foreach ($second as $sec)
<br>
<div class = "form-group">
{{$sec->Roll }}
&nbsp&nbsp&nbsp&nbsp
{{ $sec->Name}}
</div>
<div class = "form-group">
<!--{{Form::checkbox('agree') }}-->
<input tabindex="1" type="checkbox" value="{{$sec->Roll}}" name="" />
</div>
#endforeach
</div>
<br>
<form action ="report_generate&<?php echo $name ?>" method = "post" enctype = "multipart/form-data" >
<!--<input type = "hidden" name = "_token" value = "{{{ csrf_token() }}}"/>-->
<div class = "form-group">
<input type="submit" value= "Submit">
<center>Report</center>
</div>
</form>
</div>
</div>
</div>
Controller(for submit button):
public function report_generate($tabu)
{
$year = DB::table('sub')->select('Year')-
>where('sub.Subject_Name','=',$tabu)->get();
$sub_id = DB::table('sub')->select('Subject_Id')-
>where('sub.Subject_Name','=',$tabu)->get();
ob_start();
echo $year;
$output=ob_get_contents();
ob_end_clean();
if ( $output=='[{"Year":1}]')
{
$req = "first";
}
elseif ( $output=='[{"Year":2}]')
{
$req = "second";
}
elseif ( $output=='[{"Year":3}]')
{
$req = "third";
}
elseif ( $output=='[{"Year":4}]')
{
$req = "fourth";
}
$final = DB::table($req)->get();
//dd($final);
//$columns = Schema::getColumnListing($req);
//dd($sub_id);
ob_start();
echo $sub_id;
//dd($sub_id);
$va=ob_get_clean();
$va = stripslashes($va);
$txt = rtrim($va,"}]");
$txt = ltrim($txt,"[{Subject_Id:");
$txt = ltrim($txt,"Subject_Id:");
$txt = explode(":",$txt);
$txt = str_replace('"','', $txt);
//dd($txt[1]);
$columns = Schema::getColumnListing($req);
//dd($columns);
//dd($txt);
foreach ($columns as $col)
{
//dd("Y");
if($col == $txt[1])
{
$got=DB::table($req)->select($col)->get();
//dd($got);
foreach($got as $g)
{
//want to increment that cell value
}
}
}
}
Looks like your checkboxs are outside of the form divs which is an issue. You also seem to be skipping over the Laravel features, for example having a Sub Model you can call on, or using the Request facade. Also not sure why you're using ob for those string comparisons (might actually want to look at Switch for that long elseif block) Lastly, you might want to to use a raw DB statement to do the increments within a SQL query
DB::statement("UPDATE " . $table . " set " . $column . " to " . $column . " + 1 WHERE id IN (" implode(', ', $ids) . ')")

Form dropdown is giving me index and not the text

Can you help out a new learner of Codeigniter? for some reason my form dropdown is giving me the index as input->post. I just need the text selected.
Model
function get_items(){
$this->db->select('item_name');
$this->db->from('commissary_items');
$query=$this->db->get();
$result=$query->result();
$item_names=array('-SELECT-');
for($i=0;$i<count($result);$i++){
array_push($item_names,$result[$i]->item_name);
}
return $item_names;
}
View
<div class="form-group">
<div class="row colbox">
<div class="col-lg-4 col-sm-4">
<label for="item_name" class="control-label">Item</label>
</div>
<div class="col-lg-8 col-sm-8">
<?php
$attributes = 'class = "form-control" id = "item_name"';
echo form_dropdown('item_name',$item_name,set_value('item_name'),$attributes);?>
<span class="text-danger"><?php echo form_error('item_name'); ?></span>
</div>
</div>
</div>
Controller
public function new_inventory(){
$data['item_name']=$this->commissary_model->get_items();
$this->form_validation->set_rules('date_added','Date Added','required');
$this->form_validation->set_rules('item_name','Item Name','callback_combo_check');
$this->form_validation->set_rules('quantity','Quantity','required');
$this->form_validation->set_rules('amount','Amount','required|numeric');
$this->form_validation->set_rules('username','User Name');
if($this->form_validation->run()==FALSE){
// $data="";
$this->load->view('new_inventory_view',$data);
}else{
$data=array(
'date_added'=>#date('Y-m-d',#strtotime($this->input->post('date_added'))),
'item_name'=>$this->input->post('item_name'),
'quantity'=>$this->input->post('quantity'),
'amount'=>$this->input->post('amount'),
'username'=>$this->session->userdata('username')
);
$this->db->insert('add_inventory',$data);
$this->session->set_flashdata('msg','<div class="alert alert-success text-center">Item added to inventory.</div>');
redirect('commissary/added_to_inventory');
}
}
Instead of the "text value" inside the form dropdown, I get the index 1 or 2 or 3 or 4 or 5 etc.... Thank you.
That is how <select> options work - the value of the select option is returned.
If you want the text you will have to setup $item_names differently and have the index be the same as the text. Easily accomplished with a little restructuring in the model.
function get_items()
{
$this->db->select('item_name');
$this->db->from('commissary_items');
$query = $this->db->get();
$result = $query->result();
$item_names = array();
foreach($result as $item)
{
$item_names[$item->item_name] = $item->item_name;
}
return $item_names;
}

Resources