Calling save() on a model will update every row in the database - php

I've got the following function in a migration file. The migration is to add a new column, and then update the columns of the existing entries:
<?php
private function updatePlans()
{
$plans = PlanProvider::query()->get();
foreach ($plans as $plan) {
$plan->num_adults = 1;
if (stripos($plan->rate_name, 'couple') !== false) {
$plan->num_adults = 2;
}
$plan->save();
}
}
Now, what's happening here is that when I call save(), it's updating EVERY model, instead of the one inside the loop. I have a similar function for another migration, and it works as expected. Why would this update every model rather than just the one?

$plans is a Collection that contains all your "plans".
Your $plan->save(); is outside your if conditions, so obviously it updates every single row, no matter if it has 1 or 2 num_adults

public function store(Request $request)
{
$this->validate($request,[
'email' => 'required|email|unique:subscribers'
]);
$subscriber = new Subscriber();
$subscriber->email = $request->email;
$subscriber->save();
Toastr::success('You are Successfully Added Our Subscriber List:)','Success');
return redirect()->back();
}

you can try this
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class PlanProvider extends Model
{
protected $table = 'plan_provider';
protected $guarded = [];
public $timestamps = false;
}
private function updatePlans()
{
$plans = PlanProvider::findOrFail(id);
$plans->num_adults = 1;
$plans->save();
return redirect()->back();
}

Related

PHP LARAVEL Update with save() doesn't work sometimes

I have a strange problem. I'm trying to update a database entry with the save function, but the changed columns only update sometimes but most times they do not change yet I don't get any errors.
This is the code in my update function:
public function editadvocatedetails(Request $request){
try {
##get original data
$oldclaimantdets = Clthirdparties::where('claimant_code',$request->claimant_code)->first();
// ##get new data
$claimant_dets = Clthirdparties::where('record_type',$oldclaimantdets->record_type)->where('code',$oldclaimantdets->code)->first();
$claimant_dets->name = $request->name;
$claimant_dets->record_type = $request->record_type;
$claimant_dets->claimant_type = $request->claimant_type;
$claimant_dets->e_mail=$request->e_mail;
$claimant_dets->id_no=$request->id_no;
$claimant_dets->pin_number = $request->pin_number;
$claimant_dets->mobile = $request->mobile;
// // dd($claimant_dets);
$claimant_dets->save();
// dd($claimant_dets);
$mm = $claimant_dets->getChanges();
$user = Auth::user()->user_name;
$process = 'Update Claimant Details';
$claimant_code = $request->claimant_code;
$yy = $this->log_data($mm,$claimant_dets,$user,$process,$claimant_code);
Session::flash('success,'.$request->name.' details has been updated');
return redirect()->back();
} catch (\Throwable $th) {
Session::flash('error,'.$request->name.' failed to be updated');
return redirect()->back();
}
}
My Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Clthirdparties extends Model
{
protected $connection = 'oracle';
protected $table='clthirdparties';
public $timestamps=false;
public $keyType = 'string';
public $primaryKey='claimant_code';
public $incrementing=false;
protected $guarded = [];
}
When I print the values before the save, I get the correct values for both the old and new data.
It looks like the save() doesn't execute. The redirect is executed.
I'm aware of the update() method, but I used this way for updating entries in my database a lot and until now I never had any problems and I don't get where the problem is.
In the meantime I have reverted to update() to run the update query to solve the problem. But I still want to know why it is happening?
Maybe someone has an idea?
Sometimes hmm..., save() method is formally dependent on $fillable attribute array in the model. So, try defining fillable attributes.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Clthirdparties extends Model
{
protected $connection = 'oracle';
protected $table='clthirdparties';
public $timestamps=false;
public $keyType = 'string';
public $primaryKey='claimant_code';
public $incrementing=false;
protected $guarded = [];
protected $fillable = ['name','record_type','claimant_type','e_mail','id_no','pin_number','mobile',] ; //include all your attributes here.
}

PHP Laravel save() is not updating record

I am a beginner in laravel. I was updating records but I can't figure out what is wrong with my $student->save();
My controller code is as follows
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Student;
use PHPUnit\Framework\MockObject\Builder\Stub;
class HomeController extends Controller
{
public function read() {
$students = Student::all();
return view('read',['Students'=>$students]);
}
public function insert() {
return view('insert');
}
public function insertPost(Request $req) {
$student=new Student();
$student->Name = $req->input('name');
$student->Marks = $req->input('marks');
$student->save();
return redirect('/');
}
public function update($id) {
$student = Student::find($id);
return view('update',['Student'=>$student]);
}
public function delete($id) {
$student = Student::find($id);
$student->delete();
}
public function updatePost(Request $req) {
$student = Student::find($req->input('id'));
$student->Name=$req->input('name');
$student->Marks=$req->input('marks');
$student->save();
// Student::where('ID',$req->input('id'))
// ->update(['Name'=>$req->input('name'),
// 'Marks'=>$req->input('marks')]);
return redirect('/');
}
}
The Main main in updatePost(); is causing the records not updating
$student = Student::find($req->input('id'));
$student->Name=$req->input('name');
$student->Marks=$req->input('marks');
$student->save();
I changed the way of updating records to
Student::where('ID',$req->input('id'))
->update(['Name'=>$req->input('name'),
'Marks'=>$req->input('marks')]);
and it worked. But I wanted to know at which part I was making mistake in it.
You need to set your primary key to 'ID'
By default the primary key or PK name is 'id'
But in your code it changed to 'ID'
So you need to go to your User.php model class
and add this line
public $primaryKey = 'ID';
One thing you can try is using Laravel's update method. update will handle the save internally.
$student = Student::findOrFail($req->input('id')));
$student->update([
'Name' => $req->input('name'),
'Marks' => $req->input('marks'),
]);

Load Eloquent Model Relationships Child Nodes in Laravel 5.1

I can't return $parent->child() | I get null;
Parent Model
class PrinterSetting extends Model
{
protected $table = 'printer_settings';
//fillables here
protected $with = ['copies'];
public function copies(){
return $this->hasMany(\App\DB\PrinterCopy\PrinterCopy::class, 'printer_id');
}
}
Child Model
class PrinterCopy extends Model
{
protected $table = 'printer_copies';
public function printer(){
return $this->belongsTo(\App\DB\PrinterSetting\PrinterSetting::class, 'id', 'printer_id');
}
}
Code in Controller:
$availablePrinters = $this->printerSetting->where('is_active', 1)->get();
foreach($availablePrinters as $availablePrinter)
{
//working
foreach($availablePrinter->copies() as $copy)
{
//Not working
}
}
I can't find the reason why it's not working.
I Tried to dump $availablePrinter->copies and it work, but ofcourse I can't insert it on foreach() loop.
Please help.
$availablePrinter->copies() return Query builder, you have to use $availablePrinter->copies which is Collection that you can add in loop, Try this
$availablePrinters = $this->printerSetting->where('is_active', 1)->get();
foreach($availablePrinters as $availablePrinter)
{
//working
foreach($availablePrinter->copies as $copy)
{
dd($copy)
}
}
Side note, also fix your belongsTo relation in PrinterCopy model, it should be like this
public function printer(){
return $this->belongsTo(\App\DB\PrinterSetting\PrinterSetting::class,'printer_id');
}

updateOrCreate cause ErrorException in laravel

I wrote a code to login or register users.I used updateOrCreate function to add user if not exist an update a column that is name is verifcode if user exist
controller
users Table:
id(auto increment primary key)|phone|verifcode|timeStmp
---------------------------------
$phone=Input::get('phone');
$code=rand(1001,9999);
$user = new user;
$user = array('phone'=>$phone);
user::updateOrCreate($user,['verifcode' => $code]);
Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class user extends Model
{
protected $table = 'users';
protected $fillable = array('phone', 'verifcode','timeStmp');
protected $guarded = array('id');
protected $primaryKey = "id";
public $incrementing = false;
const CREATED_AT= false;
const UPDATED_AT = false;
}
with this code i have folowing error:
array_key_exists(): The first argument should be either a string or an integer that point to vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasAttributes.php file.
i just know that error point to secound argument of UpdateOrCreate function.
thanks for help
If you see at the Model class of laravel framework code, you can note, that updated_at is stored only when it is not dirty.
if (! $this->isDirty(static::UPDATED_AT)) {
$this->setUpdatedAt($time);
}
But isDirty method checks for nulls only.
public function isDirty($attributes = null)
{
$dirty = $this->getDirty();
if (is_null($attributes)) {
return count($dirty) > 0;
}
if (! is_array($attributes)) {
$attributes = func_get_args();
}
foreach ($attributes as $attribute) {
if (array_key_exists($attribute, $dirty)) {
return true;
}
}
return false;
}
So just substitute false with NULL.
If you take a look at the Laravel documentation, you're just using the updateOrCreate method wrong. Look at the flight example there.
In your case it should look like this:
$phone = \Input::get('phone')
$code = rand(1001, 9999);
$user = User::updateOrCreate(
['phone' => $phone],
['verifcode' => $code, 'timeStmp' => \Carbon::now()->timestamp]
);
finally i solve it. by adding Created_at and Update_at columns to table and adding this two coulmn to $guarded in model like this protected $guarded = array('id','CREATED_AT','UPDATED_AT'); and then problem fixed
thanks for help
$phone=Input::get('phone');
$code=rand(1001,9999);
user::updateOrCreate(
['phone' => $phone]
['verifcode' => $code]
);
See if it is work for you.

How to dynamically set table name in Eloquent Model

I am new to Laravel. I am trying to use Eloquent Model to access data in DB.
I have tables that shares similarities such as table name.
So I want to use one Model to access several tables in DB like below but without luck.
Is there any way to set table name dynamically?
Any suggestion or advice would be appreciated. Thank you in advance.
Model:
class ProductLog extends Model
{
public $timestamps = false;
public function __construct($type = null) {
parent::__construct();
$this->setTable($type);
}
}
Controller:
public function index($type, $id) {
$productLog = new ProductLog($type);
$contents = $productLog::all();
return response($contents, 200);
}
Solution For those who suffer from same problem:
I was able to change table name by the way #Mahdi Younesi suggested.
And I was able to add where conditions by like below
$productLog = new ProductLog;
$productLog->setTable('LogEmail');
$logInstance = $productLog->where('origin_id', $carrier_id)
->where('origin_type', 2);
The following trait allows for passing on the table name during hydration.
trait BindsDynamically
{
protected $connection = null;
protected $table = null;
public function bind(string $connection, string $table)
{
$this->setConnection($connection);
$this->setTable($table);
}
public function newInstance($attributes = [], $exists = false)
{
// Overridden in order to allow for late table binding.
$model = parent::newInstance($attributes, $exists);
$model->setTable($this->table);
return $model;
}
}
Here is how to use it:
class ProductLog extends Model
{
use BindsDynamically;
}
Call the method on instance like this:
public function index()
{
$productLog = new ProductLog;
$productLog->setTable('anotherTableName');
$productLog->get(); // select * from anotherTableName
$productLog->myTestProp = 'test';
$productLog->save(); // now saves into anotherTableName
}
I created a package for this: Laravel Dynamic Model
Feel free to use it:
https://github.com/laracraft-tech/laravel-dynamic-model
This basically allows you to do something like this:
$foo = App::make(DynamicModel::class, ['table_name' => 'foo']);
$foo->create([
'col1' => 'asdf',
'col2' => 123
]);
$faz = App::make(DynamicModel::class, ['table_name' => 'faz']);
$faz->create([...]);

Categories