How to delete data using join in yii2 - yii2

I am using following query for delete all corresponding data to relate on given id My code:
public function actionDeletebyajax()
{
$pid = $_POST['id'];
if($pid) {
$this->findModel($pid)->delete();
Profile::deleteAll('user_id ='.$pid);
UserLoyalty::deleteAll('store_id ='.$pid);
Workorderpopup::deleteAll('workorder_id ='.$pid);
Deal::deleteAll('workorder_id ='.$pid);
WorkorderCategory::deleteAll('workorder_id ='.$pid);
store::deleteAll('owner ='.$pid);
workorders::deleteAll('workorder_id ='.$pid);
echo $pid; exit;
}
}
But here What i want Workorderpopup has a child table Workorderpopup_child i want delete all child record to but child table has no any relation with $pid Is there Any way to delete child's records too ?

Assuming that relation is workorderpopup_child.workorderpopup_id -> workorderpopup.id.
It could be something like this
Cascade delete by IN condition
$workorderpopups = Workorderpopup::find()
->select('id')
->where(['workorder_id' => $pid])
->asArray()->all();
Workorderpopup_child::deleteAll(['in', 'workorderpopup_id', array_values($workorderpopups)]);
Or like this:
Cascade delete by relation unlinking
$workorderpopups = Workorderpopup::find()
->select('id')
->where(['workorder_id' => $pid])
->asArray()->all();
foreach ($workorderpopups as $workorderpopup) {
$workorderpopup->delete();
}
and then override your Workorderpopup->delete() as follows
/**
* #inheritdoc
*/
public function delete()
{
$this->unlinkAll('workorderpopup_child', true);
return parent::delete();
}
and make sure you have corresponding relation workorderpopup_child in Workorderpopup class:
/**
* #return \yii\db\ActiveQuery
*/
public function getWorkorderpopup_child()
{
return $this->hasMany(Workorderpopup_child::className(), ['workorderpopup_id' => 'id']);
}
p.s. i haven't tested the code above, so here can be some mistakes

Related

on delete cascade laravel

Morning everyone,
I have foreign keys set to on delete cascade in laravel 5 and mysql on a couple of tables where the existence of a employee depends on the existence of the country he was born in.
$table->foreign('id_estado_municipio')
->references('id_estado_municipio')
->on('cat_municipios')
->onDelete('cascade')
->onUpdate('cascade');
Problem is when I delete the country, the employee that must get erased along with it, gets erased from the database, but the employee's record keeps on showing at the index view.
Have tried setting engine to InnoDB in the config file, model observers to delete dependents but still can't figure out how to make it work.
Hopefully someone can give some light. It would be very much appreciate it.
Here you are my models and modelcontrollers
class Municipio extends Model
{
//
protected $table = 'cat_municipios';
protected $primaryKey = 'id_estado_municipio';
...
public function trabajadores()
{
return $this->hasMany(Trabajador::class,'id_trabajador');
}
protected static function boot() {
parent::boot();
static::deleting(function($municipio) {
// delete related stuff ;)
$municipio -> trabajadores() -> delete();
});
}
class MunicipioController extends Controller
{
...
public function destroy($id)
{
//
$municipio = Municipio::findOrFail($id);
$municipio -> trabajadores() -> delete();
$destruido = Municipio::destroy($id);
if($destruido)
return redirect()->route('Municipio.index')->with('info','Municipio eliminado con éxito.');
else
return redirect()->route('Municipio.index')->with('error','Imposible borrar Municipio.');
}
}
////////////////////////////////////////
class Trabajador extends Model
{
//
protected $table = 'trabajadors';
protected $primaryKey = 'id_trabajador';
...
public function municipio()
{
return $this->belongsTo(Municipio::class,'id_estado_municipio');
}
...
}
class TrabajadorController extends Controller
{
public function index()
{
//
$criterio = \Request::get('search'); //<-- we use global request to get the param of URI
$estadosciviles = EstadoCivil::orderBy('id_estado_civil')->paginate(50);
$estados = Estado::orderBy('id_estado') -> paginate(50);
$municipios = Municipio::orderBy('id_estado_municipio')->paginate();
$religiones = Religion::orderBy('id_religion')->paginate();
$trabajadores = Trabajador::where('nombre', 'like', '%'.$criterio.'%')
->orwhere('id_trabajador',$criterio)
->orwhere('a_paterno',$criterio)
->orwhere('a_materno',$criterio)
->orwhere('curp',$criterio)
->orwhere('rfc',$criterio)
->orwhere('seguro_social',$criterio)
->sortable()
->orderBy('id_trabajador')
->orderBy('nombre')
->paginate();
return view('Trabajador.index', array('trabajadores' => $trabajadores,'estadosciviles' => $estadosciviles,'estados' => $estados,'municipios' => $municipios,'religiones' => $religiones));
}
...
}

how to add extra element in laravel collection

i would like to know how can i add extra column in laravel collection, return from database. for instance.
User Model
User->id
User->name
Reservation Model
Reservation->user_id
Reservation->id
now
$users = User::all();
$user_reservation = Reservation::all();
foreach ($users as $user)
{
foreach ($user_reservation as $ur)
{
if ($user->id == $ur->user_id)
{
//Add extra column in to the users model
}
}
}
Laravel has a something called $appends with Accessors. how to use it
Define $append in the model where you want to add custom collection. in my case User model
class User extends Model{
protected $appends = ['user_eservation'];
public function getUserReservations($id)
{
return User::where('id', $id)->first();
}
public function getUserReservationAttribute()
{
return $this->getUserReservations(Auth::user()->id);
}
}
and now you can call the custom attribute which is not available in the database , by calling the getUserReservatoin function.
for instance
$users = User::all();
$user_reservation = Reservation::all();
foreach ($users as $user)
{
foreach ($user_reservation as $ur)
{
if ($user->id == $ur->user_id)
{
$user->getUserReservations();
}
}
}
$user->push(['extra_column' => $value]);

Laravel Autocomplete using foreign key to show data from another table

i have created an auto complete search box in controller of 'booking' table successfully , but i want the auto complete search box to show data from another table 'patient' that have a one to many relationship with "booking" table according to a specific condition using 'where' condition ,
This is the Booking Controller that i add autocomplete in it:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Booking;
use App\Patient;
use App\User;
use Session;
use DB;
use Auth;
use Input;
class BookingController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$search = \Request::get('search');
$bookings = Booking::whereHas('patient', function ($query) use ($search) {
$query->where('patient_name', 'like', '%' . $search . '%');
})->where('status','=', null)->whereHas('patient', function ($query){
$query->where('company_id','=' ,Auth::user()->company_id);
})->paginate(10);
return view('booking.index')->withBookings($bookings);
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function autoComplete(Request $request) {
$query = $request->get('term','');
$bookings=Booking::whereHas('patient', function ($query){
$query->where('company_id','=' ,Auth::user()->company_id);
})->$data=array();
foreach ($bookings as $booking) {
$data[]=array('value'=>$booking->patient->patient_name,'id'=>$booking->id);
}
if(count($data))
return $data;
else
return ['value'=>'No Result Found','id'=>''];
}
and this is the Booking Model :
class Booking extends Eloquent
{
public function patient()
{
return $this->belongsTo('App\Patient');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
and this is the patient Model:
class Patient extends Eloquent
{
public function booking()
{
return $this->hasMany('App\Booking');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
and i used this code in view :
{!! Form::text('search_text', null, array('placeholder' => 'Search Text','class' => 'form-control','id'=>'search_text')) !!}
i want to show data from "patient" table and there is a one to many relationship between "booking" and "patient" table and i have successfully made a search box to search in patient table as you can see in index function , but i dont know to show data from "patient" table using where condition to show patient_name that his company_id equal Authenticated user company_id
Sorry for my Bad Language .

Yii2 relation between three table using ActiveRecord

I have three tables in mysql database like this picture below :
Now, with gii, I create those model like this :
For table BuktiPenerimaan
class BuktiPenerimaan extends \yii\db\ActiveRecord{
/**
* #return \yii\db\ActiveQuery
*/
public function getInvoiceReports()
{
return $this->hasMany(InvoiceReport::className(), ['bukti_penerimaan_id' => 'id']);
}
}
And InvoiceReports:
class InvoiceReport extends \yii\db\ActiveRecord{
/**
* #return \yii\db\ActiveQuery
*/
public function getInvoiceReportDetails()
{
return $this->hasMany(InvoiceReportDetail::className(), ['invoice_id' => 'id']);
}
My question is, how to access all record in table invoice_report_detail if I created an object that came from BuktiPenerimaan.
I use like this :
$model = $this->findModel($id); // model Bukti Penerimaan.
$dataInvoice = $model->invoiceReports; //exist
$dataInvoiceDetail = $model->invoiceReports->invoiceReportDetails // failed, always null.
Please advixe
$dataInvoice = $model->invoiceReports; is Array of InvoiceReport object.
You need to loop over each InvoiceReport to get related InvoiceReportDetail.
$model = $this->findModel($id); // model Bukti Penerimaan.
$dataInvoice = $model->invoiceReports; //exist , but array of objects
$dataInvoiceDetail = [];
foreach($dataInvoice as $dInvoice):
$dataInvoiceDetail[] = array_merge($dataInvoiceDetail,$dInvoice->invoiceReportDetails );
endforeach;
// $dataInvoiceDetail contains all invoice_report_detail

How to get proper collection in magento grid?

I have a custom grid tab in magento category with separate table to store data.
This is table with data:
When I filter by 'Yes' under first column. It does return associated rows with ID (284 & 285) but when I select 'No', it returns IDs (281-283), it's supposed to return 283 only which is the only stream not configured already.
And when I select ANY, it returns all associated and not associated with duplicate streams to select.
What I need is show each streams once only and work with first column filter.
I think I have incorrect joins with another table which holds all the streams (groups).
This is another table
protected function _prepareCollection()
{
if ($this->getCategory()->getId()) {
$this->setDefaultFilter(array('selected_tcategoryacl'=>1));
}
/* #var $collection Technooze_Tcategoryacl_Model_Mysql4_Tcategoryacl_Collection */
$collection = Mage::getModel('tcategoryacl/tcategoryacl')->getCollection();
$collection->getSelect()->joinRight('school_group', 'school_group_id=group_id');
$collection->addFieldToFilter('school_group_status', 1);
//$collection->getSelect()->group('school_group.school_group_id');
$collection = $this->insertFakeIdsToCollection($collection);
$this->setCollection($collection);
return parent::_prepareCollection();
}
protected function _addColumnFilterToCollection($column)
{
$tcategoryaclIds = $this->_getSelectedTcategoryacl();
switch($column->getId()){
case 'selected_tcategoryacl':
if (empty($tcategoryaclIds)) {
$tcategoryaclIds = 0;
}
//$this->getCollection()->addFieldToFilter('category_id', $this->getCategory()->getId());
if ($column->getFilter()->getValue()) {
$this->removeRightJoin();
$this->getCollection()->clear()->addFieldToFilter('tcategoryacl_id', array('in'=>$tcategoryaclIds));
} elseif(!empty($tcategoryaclIds)) {
$this->getCollection()->clear();
$this->getCollection()->addFieldToFilter('tcategoryacl_id', array('nin'=>$tcategoryaclIds));
//$this->getCollection()->addFieldToFilter('school_group.school_group_id', array('nin'=>$this->_getSelectedSchoolGroupIds()));
$this->setCollection($this->insertFakeIdsToCollection($this->getCollection()));
}
break;
/*case 'allow_from':
case 'allow_to':
$this->getCollection()->addFieldToFilter($column->getId(), array('like'=>$column->getFilter()->getValue()));
break;*/
default: parent::_addColumnFilterToCollection($column);
}
return $this;
}
private function removeRightJoin(){
$this->getCollection()->clear()->getSelect()->reset('RIGHT JOIN');
}
protected function insertFakeIdsToCollection($collection)
{
$i = 0;
foreach($collection as $v){
// lets have fake ids for empty tcategoryacl_id, so checkbox can be selected
if(!$v->getData('tcategoryacl_id')){
$v->setData('tcategoryacl_id', '0' . $this->getCategory()->getId() . $i++);
$v->setId($v->getData('tcategoryacl_id'));
}
// lets auto select different groups in each row
if(!$v->getData('group_id')){
$v->setData('group_id', $v->getData('school_group_id'));
}
}
return $collection;
}
/**
* #return array
*/
protected function _getSelectedSchoolGroupIds()
{
$selected_tcategoryacl = array();
$category = $this->getCategory();
$collection = Mage::getModel('tcategoryacl/tcategoryacl')->getCollection();
$collection->addFieldToFilter('category_id', $category->getId());
foreach($collection as $v)
{
$selected_tcategoryacl[] = $v->getGroupId();
}
return $selected_tcategoryacl;
}
/**
* #return array
*/
protected function _getSelectedTcategoryacl()
{
$selected_tcategoryacl = array();
$category = $this->getCategory();
$collection = Mage::getModel('tcategoryacl/tcategoryacl')->getCollection();
$collection->addFieldToFilter('category_id', $category->getId());
foreach($collection as $v)
{
$selected_tcategoryacl[] = $v->getTcategoryaclId();
}
return $selected_tcategoryacl;
}
Update
added code on repo - https://github.com/dbashyal/Tcategory_ACL/blob/master/app/code/community/Technooze/Tcategoryacl/Block/Adminhtml/Catalog/Category/Tab/Tcategoryacl.php