Update controller to two tables many to many in Laravel - many-to-many

I having problems with update contraller ir laravel. I tried tons of things... I have a purchases table, a prices table and a pivot table (price_purchase)...
public function update(Request $request, Purchase $purchase)
{
$year = (int)Carbon::createFromFormat('Y-m-d', $purchase->purchase_date)->format('Y');
$priceToUpdate = DB::table('prices')
->select()
->where('country', $purchase->country)
->where('year', $year)
->where('medicine', $purchase->medicine)
->get();
$purchase->country = $request->country;
$purchase->patient_id = $request->patient_id;
$purchase->medicine = $request->medicine;
$purchase->quantity = (int)$request->quantity;
$purchase->purchase_date = $request->purchase_date;
$purchase->update();
$purchase->prices()->sync($priceToUpdate);
return response()->json([
"status" => true,
"message" => 'Updating data successfully',
"data-purchase" => $purchase,
], 201);
}

Related

Laravel insertGetId insert multiple rows and get inserted primary keys

The problem I am facing in the api is as follows: it is not accepting array of multiple arrays:
...
"message": "Array to string conversion",
"exception": "ErrorException",
"file": "/home/deepan8/pich.abc.com/vendor/laravel/framework/src/Illuminate/Support/Str.php",
"line": 762,
"trace": [
{
"file": "/home/deepan8/pich.abc.com/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php",
"line": 257,
"function": "handleError",
"class": "Illuminate\\Foundation\\Bootstrap\\HandleExceptions",
"type": "->"
},]
My code snippet looks like this:
$voucherArray = [];
foreach($users as $user) {
$voucherArray[] = ['voucher_code' => rand(10000, 999999),
'voucher_price' => $request->price,
'expiry_date' => $request->date,
'status' => "Active",
];
}
$ids = DB::table('pich_voucher')->insertGetId($voucherArray);
foreach($ids as $id) {
}
I need to add all the rows at once instead of adding them one by one to improve performance.
Does Laravel have some function which can provide this facility or any SQL Query where we can add multiple rows and extract their ids at the same time?
You can insert multiple rows using insertGetId() method. If you want really want to insert multiple rows and get the IDs, just use looping.
example:
$ids = [];
foreach ($users as $user) {
$voucherArray = array(
'voucher_code' => rand(10000, 999999),
'voucher_price' => $request->price,
'expiry_date' => $request->date,
'status' => "Active"
);
$ids[] = DB::table('pich_voucher')->insertGetId($voucherArray);
}
Or another way use insert method but not get the ids. if you want to get the ids you could use like below:
$voucherArray = [];
$codes = [];
foreach ($users as $user) {
$code= rand(10000, 999999);
$codes[] = $code;
$voucherArray[] = array(
'voucher_code' => $code,
'voucher_price' => $request->price,
'expiry_date' => $request->date,
'status' => "Active"
);
}
DB::table('pich_voucher')->insert($voucherArray);
$ids = DB::table('pich_voucher')->whereIn('voucher_code', $codes)->pluck('id')->toArray();

How to retrive from other table and input it again into another table in laravel?

I want to retrieve some data from 'tbl_karyawan' and input into 'tbl_absen' which is if the NIP exist from 'tbl_karyawan' then parshing some data into 'tbl_absen'. I was create the code, and the data is going well. but i have something trouble with
i want the data input in Nip_kyn be like 'KIP001' not [{"Nip_kyn":"KIP001"}].
this is my Model
public function presensi($data)
{
$isExist = DB::table('tbl_karyawan')
->where('Nip_kyn', $data)->exists();
if ($isExist) {
$namakyn = DB::table('tbl_karyawan')->where($data)->get('Nama_kyn');
$nippppp = DB::table('tbl_karyawan')->where($data)->select('Nip_kyn')->get($data);
$values = array('Nip_kyn' => $nippppp, 'Nama_kyn' => $namakyn, 'Jam_msk' => now(), 'Log_date' => today());
DB::table('tbl_absen')->insert($values);
} else {
echo 'data not available';
}
}
this is my controller
public function get()
{
$day = [
'time_in' => $this->AbsenModel->timeIN(),
'time_out' => $this->AbsenModel->timeOut(),
'break' => $this->AbsenModel->break(),
// absen here
's' => $this->AbsenModel->absensi(),
];
$data = [
'Nip_kyn' => Request()->Nip_kyn,
];
$this->AbsenModel->presensi($data);
return view('v_absen', $data, $day);
}
Yup, I finally got it, the problem is on my model.
$nama_karyawan = DB::table('tbl_karyawan')->where($data)->value('Nama_kyn');
$nipkyn = DB::table('tbl_karyawan')->where($data)->value('Nip_kyn');
I just change 'get' to 'value'.

updating 2 table column at the same time, laravel

I've been working on this for quite a while now, this problem is composed on eloquent relationships on Laravel 5.4, in this case, what I want to do is that, to accept verification of the user, and update its verif_level(column name from users) to level '2', now, the structure of the verification_accounts table consists of its id, and user_id, which is a foreign key from the users table. Now, everything works fine, but the id of the verif_level being updated on the users table is the same as the id of the verification_accounts table is 9 and its user_id is 9459, the data updated on the users table is also 9 which has the same value on the verification_accounts table. which supposed to be 9459's verif_level to be updated to level 2, here is the code for the controller:
public function updateVerification(Request $request)
{
$validator = \Validator::make($request->all(), [
'admin_feedback' => 'required',
]);
$verification = VerificationAccount::find($request->id)->load('user');
$user = User::find($request->id);
if ($validator->passes())
if($verification->verification_level == '1'){
$verification->status = 1;
$verification->proccessed_by = \Auth::user()->id;
$verification->admin_feedback = $request->admin_feedback;
$verification->save();
$user->verif_level = '2';
$user->save();
return response()->json(['success' => true,'message' => 'Verification successfully updated']);
}
else{
return response()->json(['success' => false,'message' => 'Verification already accepted']);
}
else{
return ['error' => $validator->errors()];
}
}
but when I do "$request->user_id", it returns an error of creating an array of empty object. and idea how to deal with this?

Yii2 - Integrity constraint violation – yii\db\IntegrityException

I have a rather weired error on trying to add data to my database. It keeps telling me that there is an Integrity violation, i.e.
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`ticketing_system`.`parcels`, CONSTRAINT `FK_parcels_customers_customer_id` FOREIGN KEY (`sender_id`) REFERENCES `customers` (`customer_id`))
The SQL being executed was: INSERT INTO `parcels` (`parcel_id`) VALUES (DEFAULT)
I have checked the values being inserted and all of them are picked from the referenced table. Funny bit is that when I echo the values and use them to update the database directly via SQL query on the PHPMyAdmin, the database is populated well without any problem. Again, when I try to change the order of the foreign keys as they appear on the SQL query being performed, the first one fails, meaning all the foreign keys of the model are failing.
EDITED
Here is my actionCreate in the ParcelsController
public function actionCreate()
{
$model = new Parcels();
$customerModel = new Customers();
//checking whether we are getting the logged in user id value
Yii::info("User id=".Yii::$app->user->id);
$model->received_by_id = Yii::$app->user->id;
if (Yii::$app->request->post()) {
$data = Yii::$app->request->post('Customers');
$sender_id = Customers::create([
'name' => $data['name'],
'mobile_number' => $data['mobile_number'],
'sex' => $data['sex'],
'address' => $data['address'],
'registered_by_id' => $model->received_by_id,
]);
$data = Yii::$app->request->post('Parcels');
$receiver_id = Customers::create([
'name' => $data['name'],
'mobile_number' => $data['mobile_number'],
'sex' => $data['sex'],
'address' => $data['address'],
'registered_by_id' => $model->received_by_id,
]);
$model->consignment_number = $model->generateUniqueRandomString("consignment_number");
$model->source_id = $model->receivedBy->station_id;
$model->parcel_id = Parcels::create([
'consignment_number' => $model->consignment_number,
'sender_id' => $sender_id,
'receiver_id' => $receiver_id,
'source_id' => $model->source_id,
'destination_id' => $data['destination_id'],
'type_id' => $data['type_id'],
'weight' => $data['weight'],
'cost' => $data['cost'],
'parcel_info' => $data['parcel_info'],
'received_by_id' => $model->received_by_id,
]);
// return $this->redirect(['view', 'id' => $model->parcel_id]);
} else {
return $this->render('create', [
'model' => $model, 'customerModel' => $customerModel,
]);
}
}
Customers::create function in the Customers Model
public static function create($data)
{
$model = new self;
$mobile_number = $data['mobile_number'];
$exists = $model->find()->where( [ 'mobile_number' => $mobile_number ] )->exists();
if($exists) {
$existing_customer = Customers::find()
->where('mobile_number = :mobile_number', [':mobile_number' => $mobile_number])
->one();
return $existing_customer['customer_id'];
}
else {
$model->name = $data['name'];
$model->registered_by_id = $data['registered_by_id'];
$model->mobile_number = $data['mobile_number'];
$model->sex = $data['sex'];
$model->address = $data['address'];
$model->status = 10;
$model->save();
return $model->getPrimaryKey();
}
}
Parcels::create function in the Parcels Model
public static function create($data)
{
$model = new self;
$consignment_number = $data['consignment_number'];
$receiver_id = $data['receiver_id'];
$sender_id = $data['sender_id'];
$source_id = $data['source_id'];
$destination_id = $data['destination_id'];
$type_id = $data['type_id'];
$weight = $data['weight'];
$cost = $data['cost'];
$parcel_info = $data['parcel_info'];
$received_by_id = $data['received_by_id'];
$model->save(false);
return $model->getPrimaryKey();
// echo var_dump($data);
// echo "Consignment Number: ".$consignment_number." - Sender: ".$sender_id." - Receiver: ".$receiver_id." - From: ".$source_id." - To: ".$destination_id." - Type: ".$type_id." - Weight: ".$weight." - Cost: ".$cost." - Parcel Info: ".$parcel_info." - Received By: ".$received_by_id;
}
And here is the function generateUniqueRandomString() in the Parcels Model
public function generateUniqueRandomString($attribute, $length = 10) {
$randomString = Yii::$app->getSecurity()->generateRandomString($length);
$randomString = strtoupper($randomString);
if(!$this->findOne([$attribute => $randomString]))
return $randomString;
else
return $this->generateUniqueRandomString($attribute, $length);
}
Sorry for bothering you guys. I was able to get the problem of where I was going wrong. In the create() function of the Parcels Model, I only created new variables and failed to bind them to the model, i.e.
$consignment_number = $data['consignment_number'];
$receiver_id = $data['receiver_id'];
$sender_id = $data['sender_id'];
$source_id = $data['source_id'];
$destination_id = $data['destination_id'];
$type_id = $data['type_id'];
$weight = $data['weight'];
$cost = $data['cost'];
$parcel_info = $data['parcel_info'];
$received_by_id = $data['received_by_id'];
Should have been:
$model->consignment_number = $data['consignment_number'];
$model->weight = $data['weight'];
$model->cost = $data['cost'];
$model->parcel_info = $data['parcel_info'];
$model->received_by_id = $data['received_by_id'];
$model->status = $data['status'];
$model->receiver_id = $data['receiver_id'];
$model->sender_id = $data['sender_id'];
$model->source_id = $data['source_id'];
$model->destination_id = $data['destination_id'];
$model->type_id = $data['type_id'];
Sorry for taking your time because of my carelessness.

Laravel 4 Method Improvement

I have this index method:
public function index()
{
// In the view, there are several multiselect boxes (account managers, company names and account types). This code retrives the values from the POST method of the form/session.
$company_names_value = Input::get('company_names_value');
$account_managers_value = Input::get('account_managers_value');
$account_types_value = Input::get('account_types_value');
// If there has been no form submission, check if the values are empty and if they are assign a default.
// Essentially, all of the records in the table column required.
if (is_null($company_names_value))
{
$company_names_value = DB::table('accounts')
->orderBy('company_name')
->lists('company_name');
}
if (is_null($account_managers_value))
{
$account_managers_value = DB::table('users')
->orderBy(DB::raw('CONCAT(first_name," ",last_name)'))
->select(DB::raw('CONCAT(first_name," ",last_name) as amname'))
->lists('amname');
}
if (is_null($account_types_value))
{
$account_types_value = DB::table('account_types')
->orderBy('type')
->lists('type');
}
// In the view, there is a dropdown box, that allows the user to select the amount of records to show per page. Retrieve that value or set a default.
$perPage = Input::get('perPage', 10);
// This code retrieves the order from the session that has been selected by the user by clicking on a table column title. The value is placed in the session via the getOrder() method and is used later in the Eloquent query and joins.
$order = Session::get('account.order', 'company_name.asc');
$order = explode('.', $order);
// Here we perform the joins required and order the records, then select everything from accounts and select their id's as aid. Then whereIn is used to select records where company name, account manager name and account type matches the values of the multiselect boxes or the default set above.
$accounts_query = Account::leftJoin('users', 'users.id', '=', 'accounts.user_id')
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->orderBy($order[0], $order[1])
->select(array('accounts.*', DB::raw('accounts.id as aid')));
if (!empty($company_names_value)) $accounts_query = $accounts_query->whereIn('accounts.company_name', $company_names_value);
$accounts = $accounts_query->whereIn(DB::raw('CONCAT(users.first_name," ",users.last_name)'), $account_managers_value)
->whereIn('account_types.type', $account_types_value)
->paginate($perPage)->appends(array('company_names_value' => Input::get('company_names_value'), 'account_managers_value' => Input::get('account_managers_value'), 'account_types_value' => Input::get('account_types_value')));
$accounts_trash = Account::onlyTrashed()
->leftJoin('users', 'users.id', '=', 'accounts.user_id')
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->orderBy($order[0], $order[1])
->select(array('accounts.*', DB::raw('accounts.id as aid')))
->get();
$message = Session::get('message');
$default = ($perPage === null ? 10 : $perPage);
$this->layout->content = View::make('admin.accounts.index', array(
'accounts' => $accounts,
'accounts_trash' => $accounts_trash,
'company_names' => DB::table('accounts')->orderBy('company_name')->lists('company_name', 'company_name'),
'account_managers' => DB::table('users')->orderBy(DB::raw('CONCAT(first_name," ",last_name)'))->select(DB::raw('CONCAT(first_name," ",last_name) as amname'))->lists('amname', 'amname'),
'account_types' => DB::table('account_types')->orderBy('type')->lists('type', 'type'),
'perPage' => $perPage,
'message' => $message,
'default' => $default
));
}
Basically, I am building a query that searches several tables (hence the joins). In the view a user has the ability to select multiple values from various multi-select boxes and then submit a form which will then populate the $company_names_value, $account_managers_value and $account_types_value variables.
Initially, when there is no form submission, I'm using Query Builder to select all records for each type, and then using them in the query.
It works but it is slow and messy. I was wondering if any of you Laravel 4 gurus could help me improve it further, so that the queries are faster and the code is lighter.
Thanks in advance.
This has now been refactored significantly, and it is very fast now. I've moved most of my code in to my models, as well as refactoring that code.
Here's the new index method:
public function index()
{
$account = explode(',', Input::get('account'));
$account_manager = explode(',', Input::get('account_manager'));
$account_type = explode(',', Input::get('account_type'));
$perPage = Input::get('perPage', 10);
$order = Session::get('account.order', 'company_name.asc');
$order = explode('.', $order);
$accounts = Account::accounts($order, $account, $account_manager, $account_type)->paginate($perPage)->appends(array(
'account' => Input::get('account'),
'account_manager' => Input::get('account_manager'),
'account_type' => Input::get('account_type'),
'perPage' => Input::get('perPage')
));
$accounts_trash = Account::accountsTrash($order)->get();
$message = Session::get('message');
$default = ($perPage === null ? 10 : $perPage);
$this->layout->content = View::make('admin.accounts.index', compact('accounts', 'accounts_trash', 'message', 'default'));
}
And the new getAccountByName() method in my controller that is used during my AJAX call. This should probably go in the model:
public function getAccountByName()
{
$name = Input::get('account');
return Account::select(array('id', DB::raw('company_name as text')))->where('company_name', 'like', "%$name%")->get();
}
And finally two new methods in my model for retrieving accounts and accounts trash:
public function scopeAccounts($query, $order, $account, $account_manager, $account_type)
{
$query->leftJoin('users', 'users.id', '=', 'accounts.user_id')
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->orderBy($order[0], $order[1])
->select(array('accounts.*', DB::raw('accounts.id as aid')));
if (!empty($account[0])) {
$query = $query->whereIn('accounts.id', $account);
}
if (!empty($account_manager[0])) {
$query = $query->whereIn('users.id', $account_manager);
}
if (!empty($account_type[0])) {
$query = $query->whereIn('account_types.id', $account_type);
}
}
public function scopeAccountsTrash($query, $order)
{
$query->onlyTrashed()
->leftJoin('users', 'users.id', '=', 'accounts.user_id')
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->orderBy($order[0], $order[1])
->select(array('accounts.*', DB::raw('accounts.id as aid')));
}
Again, there's probably a ton of things to get tidied up here but I'm certainly closer to a much faster and cleaner solution. Doing it like this has reduced the loading times from 12 seconds to 234ms.