Save multiple data in database column from select multiple - laravel

I want to save more than one university under one student. For html select I used
<select class="selectpicker" multiple data-live-search="true" name="university">
#foreach($districts as $row)
<option value= {{$row->name}} > {{$row->name}} </option>
#endforeach
</select>
This taking previously saved university. I am using district as university.
Controller->
public function store(Request $request)
{
Seller_info::create([
'name' => $request['name'],
'email' => $request['email'],
'passport' => $request['passport'],
'phone_number' => $request['phone_number'],
'address' => $request['address'],
'dateofbirth' => $request['dateofbirth'],
'ielts' => $request['ielts'],
'openingcharge' => $request['openingcharge'],
'serviceCharge' => $request['serviceCharge'],
'applydate' => $request['applydate'],
'visaStatus'=> $request['visaStatus'],
'country' => $request['country'],
'university'=> $request['university'],
]);
return back();
}
This is saving the students. This is a mishmash code I am sorry about that. I am working on a different for fast learning. Here I am using seller_info as student.
The data is is saving university but only one university in the database. I tried to use for loop in case of storing. But could not able to implement it properly.
My table file->
Schema::create('seller_infos', function (Blueprint $table) {
$table->id();
$table->string('name')->nullable();
$table->string('email')->unique();
$table->string('passport')->nullable();
$table->string('phone_number')->unique();
$table->string('address')->nullable();
$table->string('dateofbirth')->nullable();
$table->string('ielts')->nullable();
$table->string('openingcharge')->nullable();
$table->string('serviceCharge')->nullable();
$table->string('applydate')->nullable();
$table->string('visaStatus')->nullable();
$table->string('country')->nullable();
$table->string('university')->nullable();
$table->timestamps();
});
And model
protected $fillable = [
'name', 'email', 'passport', 'phone_number','address','dateofbirth','ielts', 'openingcharge','serviceCharge','applydate',
'visaStatus','country','university'
];

If you want to store multiple university data for one student first of all you need 3 table, students(so your Seller Info), universities and seller_info_university(will be pivot table),
seller_info_university Migration must be like;
Schema::create('seller_info_university', function (Blueprint $table) {
$table->bigInteger('seller_info_id')->unsigned();
$table->bigInteger('university_id')->unsigned();
});
Add this code your SellerInfo Model;
public function universities()
{
return $this->belongsToMany(University::class); // Your University model
}
Add this code your University Model;
public function students()
{
return $this->belongsToMany(SellerInfo::class); // Your Student(SellerInfo) model
}
In your Controller try this
$student = Seller_info::create([
'name' => $request['name'],
'email' => $request['email'],
'passport' => $request['passport'],
'phone_number' => $request['phone_number'],
'address' => $request['address'],
'dateofbirth' => $request['dateofbirth'],
'ielts' => $request['ielts'],
'openingcharge' => $request['openingcharge'],
'serviceCharge' => $request['serviceCharge'],
'applydate' => $request['applydate'],
'visaStatus'=> $request['visaStatus'],
'country' => $request['country'],
// 'university'=> $request['university'], you dont need there anymore
]);
$student->universities()->attach($request['universities']); // You can use attach(), detach() or sync() functions, you can search in Laravel Documentation
return back();
And View;
<select class="selectpicker" multiple data-live-search="true" name="universities[]">
#foreach($districts as $row)
<option value= {{$row->name}} > {{$row->name}} </option>
#endforeach
</select>

Related

How Do I Prevent Duplicate When Storing My API Fetched Data

I am fetching data from an API. I am able to store the data in my database but whenever i refresh, it stores another copy of the same set of data fetched from the API. I simply want to know how to only update the database with the new records whilst ignoring the old once stored already.
Controller
public function dashboard()
{
$client = new Client();
$uri = 'https://api.clickmeeting.com/v1/conferences/active';
$header = ['headers' => ['X-Api-Key' => '123456']];
$res = $client->get($uri, $header);
$conferences = json_decode($res->getBody()->getContents(), true);
collect($conferences)
->each(function ($conference, $key) {
ClickMeeting::create([
'conference_id' => $conference['id'],
'parent_id' => $conference['parent_id'],
'room_type' => $conference['room_type'],
'room_pin' => $conference['room_pin'],
'name' => $conference['name'],
'name_url' => $conference['name_url'],
'access_type' => $conference['access_type'],
'lobby_enabled' => $conference['lobby_enabled'],
'lobby_description' => $conference['lobby_description'],
'registration_enabled' => $conference['registration_enabled'],
'status' => $conference['status'],
'timezone' => $conference['timezone'],
'timezone_offset' => $conference['timezone_offset'],
'paid_enabled' => $conference['paid_enabled'],
'automated_enabled' => $conference['automated_enabled'],
'type' => $conference['type'],
'permanent_room' => $conference['permanent_room'],
'room_url' => $conference['room_url'],
'embed_room_url' => $conference['embed_room_url'],
]);
});
return view('admin.clickmeeting.dashboard');
}
Migration Schema
public function up()
{
Schema::create('clickmeeting', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('conference_id')->unique();
$table->string('parent_id')->nullable();
$table->string('room_type');
$table->string('room_pin');
$table->string('name');
$table->string('name_url');
$table->string('ends_at');
$table->string('access_type');
$table->string('lobby_enabled');
$table->string('lobby_description');
$table->string('registration_enabled');
$table->string('status');
$table->string('timezone');
$table->string('timezone_offset');
$table->string('paid_enabled');
$table->string('automated_enabled');
$table->string('type');
$table->string('permanent_room');
$table->string('room_url');
$table->string('embed_room_url');
});
}
Help is gratefully appreciated. Thank You
Laravel has a firstOrCreate() method, which either finds the model or creates it. Perfect for your example. The first parameter, is the columns that defines the uniqueness and the second parameter is the columns that should be added to the row. These columns are concatenated when saved. It is very uncommon and flaky, to expect such a big request to use all columns for uniqueness.
Let's imagine that these 3 columns would define a non present composite key room_type, parent_id and room_url. This can be adjusted by you to follow the correct columns.
ClickMeeting::firstOrCreate([
'parent_id' => $conference['parent_id'],
'room_type' => $conference['room_type'],
'room_url' => $conference['room_url'],
],
[
'conference_id' => $conference['id'],
'room_pin' => $conference['room_pin'],
'name' => $conference['name'],
'name_url' => $conference['name_url'],
'access_type' => $conference['access_type'],
'lobby_enabled' => $conference['lobby_enabled'],
'lobby_description' => $conference['lobby_description'],
'registration_enabled' => $conference['registration_enabled'],
'status' => $conference['status'],
'timezone' => $conference['timezone'],
'timezone_offset' => $conference['timezone_offset'],
'paid_enabled' => $conference['paid_enabled'],
'automated_enabled' => $conference['automated_enabled'],
'type' => $conference['type'],
'permanent_room' => $conference['permanent_room'],
'embed_room_url' => $conference['embed_room_url'],
],
]);

Save One-to-Many Relationship in Laravel 6

I have two Table that Transfer and Product that link One-to-Many Relationship. I'm to create relationship between Transfer and Product like Pics Below.
that get Selected Dropdown Product when Click Search.... and When Click Create save relationship Product into Transfers..
My Transfer Model
public function products()
{
return $this->hasMany(\App\Product::class);
}
My Product Model
public function transfer()
{
return $this->belongsTo(\App\Transfer::class);
}
in TransferController
public function store(Request $request)
{
$request->validate([
'from_location' => 'required',
'to_location' => 'required',
'status' => 'required',
'description' => 'nullable',
'shipping_charge' => 'nullable',
]);
$transfer = new Transfer();
$transfer->branch_id = auth()->user()->id;
$transfer->from_location = $request->input('from_location');
$transfer->to_location = $request->input('to_location');
$transfer->status = $request->input('status');
$transfer->shipping_charge = $request->input('shipping_charge');
$transfer->save();
// $products = new Product();
// $products->name = $request->input('')
return response()->json(['created' => true]);
}
I think its a dummy question, but i stuck 3 days with it. I'll appreciate of all Ur help...
You need to post the product_ids to backend that you selected,
and just update the relationship:
...
$transfer->shipping_charge = $request->input('shipping_charge');
$transfer->save();
Product::whereIn('id', $product_ids)->update(['transfer_id' => $transfer->id]);
If your products are all new, you can use saveMany:
$products = array(
new Product(['name' =>'product1', ...]),
new Product(['name' => 'product2', ...])
);
...
$transfer->save();
$transfer->products()->saveMany($products);

Laravel - Iterating pivot data (Property does not exist on this collection instance)

I have a many-to-many relationship between Order and Product
Product.php
public function orders()
{
return $this->belongsToMany(Order::class)
->withTimestamps()
->withPivot('qty');
}
Order.php
public function products()
{
return $this->belongsToMany(Product::class)
->withTimestamps()
->withPivot('qty');
}
Now whenever I try to utilize an iteration in a view (in this case I am just trying to show the form which iterates through all available Products, I always receive the error...
Property [products] does not exist on this collection instance.
create.blade.php
#foreach ($products->orders as $product)
# Order inputs are here
{{ Form::text('qty', $product->pivot->qty, [
'type' => 'tel',
'min' => 0,
'max' => 20,
'step' => 1,
'placeholder' => '0',
'class' => 'meal'
]) }}
#endforeach
I have also attempted #foreach ($products->orders as $product) and both approaches give me that same error.
I have attempted many different ways in my Controller to fix this error, here is my last attempt:
OrderControlller.php
public function create()
{
$user = Auth::user();
$products = Product::get();
$orders = $user->orders;
return view('orders.create', compact('products', 'orders', 'user'));
}
UPDATE
#alan's answer is correct, I am sure, however...
I am still getting "Property [pivot] does not exist on this collection instance" whenever I try to run an iteration.
The concept of an iteration inside of an iteration in this instance is confusing for me.
I cannot visualize how Laravel is handling the pivot connection. In tinker when I load up just the Product table, there is no qty column. (This makes sense because that is on the pivot table). This also explains this new error.
Should I be doing something in the vein of this? :
changed create.blade.php
#foreach ($products as $product)
{{ Form::text('qty', $product->orders->pivot->qty }}
OrderController.php
$user = Auth::user();
$orders = $user->orders;
$products= []; #pass products to view as an array
$p = $orders->products; #this relationship brings in pivot data?
foreach ($p as $orders) {
#would I then somehow pass just this qty here?
}
Problem is I am always getting a "Property does not exist" error, be it with 'products', 'orders', or 'pivot'.
This should work. You were trying to access the orders property on the $products variable, which is a Laravel Collection (get method on model returns a collection). So instead of doing that you just iterate through the products and access the pivot table from the individual product model.
#foreach ($products as $product)
# Order inputs are here
{{ Form::text('qty', $product->orders->pivot->qty, [
'type' => 'tel',
'min' => 0,
'max' => 20,
'step' => 1,
'placeholder' => '0',
'class' => 'meal'
]) }}
#endforeach
Update:
Actually that makes sense. A record on the pivot table defines an association between an order and a product. So for you to access a record in the pivot table you must access the product or order from its relationship. This is what I would do.
OrderController.php
$user = Auth::user();
$user->load("orders.products"); // eager load relationship to avoid N+1 problem
$orders = $user->orders;
return view('orders.create', compact('orders', 'user'));
create.blade.php
#foreach ($orders as $order)
#foreach ($order->products as $product)
{{ Form::text('qty', $product->pivot->qty, [
'type' => 'tel',
'min' => 0,
'max' => 20,
'step' => 1,
'placeholder' => '0',
'class' => 'meal'
]) }}
#endforeach
#endforeach
Some resources:
Eager loading
Many to Many relations

cakephp3- table sorting not working

Version: 3.3.*
I’m using the $paginator->sort() method to create links in the column headers for tables of paginated search results in my CMS. You should be able to click them once to sort in ascending order, and then click again to reverse into descending order. But the reverse was never working for me.
But this is not for all fields. Let say I have 5 fields.
<tr class="design">
<th scope="col"><?= $this->Paginator->sort('Students.id','Id',array('class'=>'link')); ?></th>
<th scope="col"><?php echo $this->Paginator->sort('Students.userName','Name',array('class'=>'link')); ?></th>
<th scope="col"><?php echo $this->Paginator->sort('Students.age','Age',array('class'=>'link')); ?></th>
<th scope="col"><?php echo $this->Paginator->sort('Students.currentClass','Class',array('class'=>'link')); ?></th>
<th scope="col"><?php echo $this->Paginator->sort('Students.dateJoined','Joined Date',array('class'=>'link')); ?></th>
</tr>
I can sort the table both ways using username, age, and school but not using id and joined. When I fetch the list initially I have specified in my Model function to fetch result based on id and joined in ascending order.
Is it because of this, I'm not being able to sort it in descending order?
Is there any way I can achieve this?
Controller function
public function index()
{
//Listing Students
$this->paginate = [
'finder' => 'ListStudents',
'sortWhitelist' => ['Students.id',
'Students.userName',
'Students.age',
'Students.currentClass',
'Students.dateJoined',],
'limit' => 25,
];
$students = $this->paginate($this->Students);
$this->set(compact('students'));
$this->set('_serialize', ['students']);
}
Model Function
public function findListStudents(Query $query, array $options)
{
$query
->select(['id','userName','age','currentClass','dateJoined'
])
$query->group('Students.id');
$query->order(['status' => 'asc']);
$query->order(['Students.dateJoined' => 'asc']);
$query->order(['Students.id' => 'asc']);
return $query;
}
The issue mentioned in this link is similar to the one I'm facing.I tried the solution mentioned in it but it ain't working.
To achieve this, you have to modify your controller and model functions a little bit.
First of all, add extraOptions to your controller function
public function index()
{
//Listing Students
$this->paginate = [
'finder' => 'ListStudents',
'sortWhitelist' => ['Students.id',
'Students.userName',
'Students.age',
'Students.currentClass',
'Students.dateJoined',],
'limit' => 25,
'extraOptions' =>[
'params' => $params ]
];
$students = $this->paginate($this->Students);
$this->set(compact('students'));
$this->set('_serialize', ['students']);
}
Now you need to override your dateJoined and id sort order. By default, its asc.
If user passes a specific direction, it should be taken. So, for that you need to modify your model function a little.
public function findListStudents(Query $query, array $options)
{
$query
->select(['id','userName','age','currentClass','dateJoined'
])
$query->group('Students.id');
$direction = (!empty($options['extraOptions']['params']['direction'])) ? $options['extraOptions']['params']['direction'] : 'asc';
$query->order(['status' => 'asc']);
$query->order(['Students.dateJoined' => $direction]);
$query->order(['Students.id' => $direction]);
return $query;
}
Now sorting will work fine when you are passing a specific direction.
When I fetch the list initially I have specified in my Model function
to fetch result based on id and joined in ascending order. Is it
because of this, I'm not being able to sort it in descending order?
Yes, this is the case. You can verify that by commenting out the $query->order statements in your custom finder method. You will find out that descentant sorting Students.id will work then.
I would recommend to simply leave the sorting out of the custom finder method and define the default sorting options when configuring your $paginate variable instead.
StudentsController
public function index()
{
$this->paginate = [
'finder' => 'ListStudents',
'sortWhitelist' => [
'Students.id',
'Students.userName',
'Students.age',
'Students.currentClass',
'Students.dateJoined'
],
'limit' => 25,
// add custom sorting options here
'order' => [
'Students.status' => 'asc',
'Students.dateJoined' => 'asc',
'Students.id' => 'asc'
]
];
$students = $this->paginate($this->Students);
$this->set(compact('students'));
$this->set('_serialize', ['students']);
}
StudentsTable
public function findListStudents(Query $query, array $options)
{
$query ->select([
'id', 'userName', 'age', 'currentClass', 'dateJoined'
]);
$query->group('Students.id');
// remove the sorting here
/*
$query->order(['status' => 'asc']);
$query->order(['Students.dateJoined' => 'asc']);
$query->order(['Students.id' => 'asc']);
*/
return $query;
}

Storing data to multiple tables from single form in laravel

My schemas are:
Schema::create('persons', function (Blueprint $table) {
$table->bigInteger('university_id')->unique()->unsigned();
$table->string('category');
$table->string('name');
$table->timestamps();
});
Schema::create('teachers', function (Blueprint $table) {
$table->increments('teacher_id');
$table->bigInteger('university_id')->unsigned();
$table->string('position');
$table->string('courses');
$table->integer('salary');
$table->timestamps();
});
Schema::create('students', function (Blueprint $table) {
$table->increments('student_id');
$table->bigInteger('university_id')->unsigned();
$table->string('year');
$table->string('semester');
$table->string('programme');
$table->integer('rollNum');
$table->timestamps();
});
I have a two forms with fields:
For Teachers:University ID, Name, Category, Position, Courses, Salary
For Students:University ID, Name, Category, Year, Semester, Programme, Roll Number
I tried to store data in the database through my controller in single method as follows:
After requesting all data into variables from form, I tried to store data in the following way.
University::create([
'university_id' =>$universityID,
'category' => $category,
'name' => $name
]);
//I passed values of category as Teacher when submitting from teacher form
//and Student while submitting student form.
if($category == 'Teacher'){
Teacher::create([
'university_id' => $universityID,
'position' => $position,
'courses' => $course,
'salary' => $salary
]);
}
if($category == 'Student'){
Student::create([
'university_id' => $universityID,
'year' => $year,
'semester' => $semester,
'programme' => $programme,
'rollNum' => $roll
]);
}
When i submitted Teacher's form, I was expecting that data will be stored in University and Teachers table only and it did. But there was an unexpected problem occurred. The Student table was filled with Null values. I was expecting if condition will prevent running Student::create([])
So how can I store values only in University and Teachers table when submitting from teachers form and University and Students table only when submitting from students form without having null values in either of them.
Instead of using like this, simple would be use if and else statements and that would do the job.
Example:
$university = University::create([
'university_id' =>$universityID,
'category' => $category,
'name' => $name
]);
if($category == 'Teacher') {
Teacher::create([
'university_id' => $university->id,
'position' => $position,
'courses' => $course,
'salary' => $salary
]);
else if($category == 'Student') {
Student::create([
'university_id' => $university->id,
'year' => $year,
'semester' => $semester,
'programme' => $programme,
'rollNum' => $roll
]);
}else{
//Unknown Category name
}
Let me know if that works for you. The way I see it's very simple and straight forward.

Resources