MODELS: Cannot update values in DB - laravel

I have this function to update the DB values, but one of the statements is not working. I created a relation to the table called ventas, however, it is not updating it´s value to NULL. This is my code:
public function cambiarEstatusFactura( Request $request){
try{
\DB::beginTransaction();
$factura = FacturaVenta::with('venta')->where( 'id' , $request->id )->first();
// dd('Esto : ' , $factura->venta->factura_uuid);
if( $factura->estatus == 'Timbrada' ){
$factura->estatus = 'Cancelada';
$factura->uuid = NULL;
$factura->venta->factura_uuid = NULL;
$factura->save();
}
\DB::commit();
}catch (Exception $e){
\Alert::error($e->getMessage())->flash();
return redirect('admin/finanzas/factura/venta');
}
}
The statement that is not working is:
$factura->venta->factura_uuid = NULL;
Though the other statements work seamlessly, this seems to have issues but I do not get any error messages.
Variable $factura contains FacturaVenta model and the relation venta brings the model from the table ventas, that's why I try to access to it via $factura->venta and the commented dd('Esto : ' , $factura->venta->factura_uuid); in the code brings the value correctly, that means that it's pointing correctly to the correct table but it's not being updated to NULL.
I just want to update the value from whatever it has to NULL.
Could you help me please?

Related

Call to a member function update() on null with array/checkbox/edit

Need help here i m trying to take values from checkbox s and put them into a edit to change the value "Estado" to "Expedido" but when I run the code it gives me the error"Call to a member function update() on null".I also tried find and change the default of find() to the column i want and also tried with raw postgresql code.
$chassis= $request->chassis;
$escala = $request->escala;
if(Auth::check() == true)
{
foreach($chassis as $chassis)
{
$edit = expedicoes::whereIn('Chassis', explode(',',$chassis))->first()->update(['Estado' =>'Expedido']);
}
The method update(Array) doesnt exist on a model instance, it only exists on a query builder as a Builder instance.
either remove the first() call to call update on the query builder
$edit = expedicoes::whereIn('Chassis', explode(',',$chassis))->update(['Estado' =>'Expedido']);
Or update the on the model then call save()
$edit = expedicoes::whereIn('Chassis', explode(',',$chassis))->first();
if ($edit) {
$edit->Estado = 'Expedido';
$edit->save();
}
I suggest you remove the update call from the foreach loop, gather all "chassis" and run a single query
$extractedChassis = [];
foreach($chassis as $chassi)
{
$extractedChassis = array_merge($extractedChassis , explode(',',$chassi));
}
expedicoes::whereIn('Chassis', $extractedChassis)->update(['Estado' =>'Expedido']);
this code return null
expedicoes::whereIn('Chassis', explode(',',$chassis))->first()
so you have no items that Chassis in explode(',',$chassis)
to solve this you can check if its not return null then update it
$expedicoes = expedicoes::whereIn('Chassis', explode(',',$chassis))->first();
if(expedicoes ){
expedicoes ->update(['Estado' =>'Expedido']);
}
but i think your problem in column name so try to use chassis instead of Chassis
and estado instead of Estado

Laravel: Using OR in multiple Where Claus

Converting SQL to Laravel format is still a bit confusing for me. I need to use OR. If onloan = NULL OR 0 then display record.
The code below can only detect the 0 but not the NULL.
public function finditembarcode () {
if ($finditembarcode = \Request::get('q')) {
$itembarcode = Item::where(Item::raw("BINARY `itembarcode`"), $finditembarcode)
->where('onloan','=', NULL OR 0)
->paginate();
}else{
$itembarcode = ''; //If nothing found, don't return anything.
}
return $itembarcode;
}
I also tried but get the same result as code above.
->where('onloan','=', NULL || 0)
Laravel Database Query Builder whereNull / whereNotNull / orWhereNull / orWhereNotNull
->where('onloan', 0)->orWhereNull('onloan')

Laravel 5.7 many to many sync() not working

I have a intermediary table in which I want to save sbj_type_id and difficulty_level_id so I have setup this:
$difficulty_level = DifficultyLevel::find(5);
if ($difficulty_level->sbj_types()->sync($request->hard, false)) {
dd('ok');
}
else {
dd('not ok');
}
Here is my DifficultyLevel.php:
public function sbj_types() {
return $this->belongsToMany('App\SbjType');
}
and here is my SbjType.php:
public function difficulty_levels() {
return $this->hasMany('App\DifficultyLevel');
}
In the above code I have dd('ok') it's returning ok but the database table is empty.
Try to change
return $this->hasMany('App\DifficultyLevel');
to
return $this->belongsToMany('App\DifficultyLevel');
The sync() method takes an array with the id's of the records you want to sync as argument to which you can optionally add intermediate table values. While sync($request->hard, false) doesn't seem to throw an exception in your case, I don't see how this would work.
Try for example:
$difficulty_level->sbj_types()->sync([1,2,3]);
where 1,2,3 are the id's of the sbj_types.
You can read more about syncing here.

Single transaction on multiple model function with CodeIgniter

I need to insert into 2 tables if anything goes wrong while inserting in any of the table I want to rollback commited queries.
I wrote queries inside controller
for example:
$this->db->trans_start();
$this->db->insert_batch('market_users_mapping', $marketData);
$this->db->insert_batch('maincategory_users_mapping', $maincategoryData);
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE) {
throw error
}
This works perfectly. But I think it's not good practice to write queries inside controller. So I did this, called model function and I wrote those insert_batch queries in respective model function.
$this->db->trans_start();
$this->maincategory_model->function_name()
$this->market_model->function_name();
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE) {
throw error
`enter code here`
}
but this didnt work as expected
You changed places of queries in those examples regarding names in case it matters. I think that you can't have tied transactions between different methods (your second example). But you can and should set your DB related code to model.
So make those queries in model:
// controller code
$this->db->trans_start();
$this->maincategory_model->first_function($maincategoryData);
$this->market_model->second_function($marketData);
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE) {
throw error
`enter code here`
}
// Maincategory_model code
public function first_function($maincategoryData)
{
return $this->db->insert_batch('maincategory_users_mapping', $maincategoryData);
}
// Market_model code
public function second_function($marketData)
{
return $this->db->insert_batch('market_users_mapping', $marketData);
}
First shift your db related operation in module and then start transaction.
Sample code in module,
First module :
function insert_data_market_maincategory($marketData,$maincategoryData)
{
$status = TRUE;
$this->db->trans_start();
$this->db->insert_batch('market_users_mapping', $marketData);
$this->second_module_name->maincategoryData($maincategoryData)
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE) {
$status = FALSE;
}
return $status;
}
second module :
function maincategoryData($data)
{
$this->db->insert_batch('table_name', $data);
}
and your controller call this function
sample code in controller,
function inser_user_data()
{
$result = $this->module_name->maincategoryData($marketData,$maincategoryData)
if($result == FALSE)
{
throw error
`enter code here`
}
else
{
//data inserted successfully
}
}
I am using CI 3 and I can use single transaction on multiple model in Controller.
I have tried to insert error data to test if rollback or not, the transaction is successfully rollback.
I did not use Tpojka's anwser but my model methods return true or false. Everything seems okay.

Why isn't my Where working as I think it should?

I'm trying to get some data from a database whose results can be more than one row.
I've the following code for that:
public System.Linq.IQueryable<Users> getUser2(string idUser)
{
try
{
using (Entities c = new Entities())
{
c.ContextOptions.LazyLoadingEnabled = false;
c.ContextOptions.ProxyCreationEnabled = false;
return c.Users.Include("Empresas").Where(x => x.Login == idUser && x.Empresas.Activa == true);
}
}
catch (Exception ex)
{
throw ex;
}
}
But it doesn't seem to get any result, it shows something like a badly formed Iqueryable, I mean if I expand its results view I can see a message that says "ObjectContext instance has been eliminated and cannot be used for operations that need a connection" If I try to access any Users element with the function ElementAt(index) I get an IndexOutOfBounds error as it looks like it has no data if watched on debug mode.
I've deduced that it's Where fault because this code Works fine in returning the first user it finds that fulfills the condition:
public Users getUser(string idUser)
{
try
{
using (Entities c = new Entities())
{
c.ContextOptions.LazyLoadingEnabled = false;
c.ContextOptions.ProxyCreationEnabled = false;
return c.Users.Include("Empresas").FirstOrDefault(x => x.Login == idUser && x.Empresas.Activa == true);
}
}
catch (Exception ex)
{
throw ex;
}
}
Does that Where work differently than what I think I should? If then, how could I get several data that fulfills the conditions I'm passing the same as in getUser but for several rows?
Thanks for your attention.
You need to enumerate the result, so after the "where" statement add. ToList() which will enumerate and execute the query against your database. FirstOrDefault is executing the query thats why you get a result.
You need to check the deferred methods and understand how they work.
EDIT
The following are some links to show you the deference between the Deferred method vs Immediate methods in LINQ
1- http://www.dotnetcurry.com/showarticle.aspx?ID=750
2- http://www.codeproject.com/Articles/627081/LINQ-Deferred-Execution-Lazy-Evaluation
3- http://visualcsharptutorials.com/linq/deferred-execution
Hope that helps.

Resources