laravel update shouldn't do anything if no value changed - laravel

If I open a form to edit and without changing any value just hit Submit button to update, it updates the row in the table i.e. it changes the updated_at time and even executes some code in bootXXXX(static::saving(function($model) {}) function.
I do not want that to happen.
How can I find If user changed nothing and its a blank submit button hit?
Of course before update I can fetch the current values and compare them with input $request->all() and decide to update or not, but Is there any better way to do so the laravel way?
Thanks,
K

you have 2 methods one is getDirty() by using this you will get current changed input value, another one is getOriginal() if you use that you will get what previous data you have
By using those 2 methods i am giving here a example,may be it will help you
static::saving(function($model)
{
foreach($model->getDirty() as $attribute => $value){
$original= $model->getOriginal($attribute);
echo "Changed $attribute from '$original' to '$value'<br/>\r\n";
}
return true; //if false the model wont save!
});

Related

laravel - update the model(!) without selecting first

I have the following ResearchModel (eloquent):
$research = new ResearchModel();
$research->id = 2;
$research->name = "test";
$research->save();
I am expecting Laravel to run an update statement (because I set the id), but it runs an insert statement instead.
$research->update(); wont do anything.
I don't want to use array in this case because I need the eloquent model events to be triggered.
I also don't want to run ResearchModel::find(2); before, this will cause significant performance problems in my use-case.
Is there any way to tell Laravel to update by the id?
Thanks
If you don't want to "select" first. Then you can update directly. This will run only one query.
$research = ResearchModel::where('id',2)->update([
'name' => 'test',
]);
A dirty solution:
// Create an instance without insert to database.
$instance = new ResearchModel;
$instance->id = 2;
$instance->name = "test";
// Set the instance status directly.
$instance->exists = true;
// Update database without model.
ResearchModel::where('id', $instance->id)
->update(['name' => $instance->name]);
// Manually trigger event.
event('eloquent.updating: App\ResearchModel', $instance);
The premise of this method is that you already have the required data. If the data required for the event must be read from the DB, then this method is useless.
Find by id
$research = ResearchModel::find(2);
Then you can run update function
$research->update([ 'name' => "test"]);
and if u don't want to use
ResearchModel::find(2);
then u have to use route binding
https://laravel.com/docs/6.x/routing#implicit-binding

Laravel update query use

I used this query to update the status column.
$val="1";
vehicles::where('id' , '=' , $veh_status)->update(['status' => $val]);
But when I submitted the status value doesn't change.
you can trace your query by using ->toSql() method !
try this to find whats happening in back
Not sure what the problem is there because you haven't given much info to work with, but you can check these suggestions:
Check if the column is set to be mass assignable in the model class, that is, it is in the fillable[] array.
make sure the id you pass to the where() function is valid.
Try using another function, save() which will achieve the same results you seek, like this;
// filter the vehicle
$vehicle = vehicles::where('id', '=', $veh_id)->first();
or
$vehicle = vehicles::find($veh_id);
$vehicle->status = 1;
$vehicle->save();
Lastly, I noticed your id variable you pass to the where the () function is called $veh_status "presumably - vehicle status" and not $veh_id, "presumably - vehicle id" so probably check that out.
Ref: Laravel Model Update documentation

Laravel 5 session array update

I am having trouble while updating session array value in laravel 5. Here is my function,
public function postCartItemAdd()
{
$id = Request::input('id');
Session::push('items', $id);
dd(Session::all());
}
Instead of pushing a new id into the array it just replaces the existing value leaving single item. Am I doing something wrong?
The problem is the session is saved as a flash data. So, you need to save the session whenever you push the data.
$request->session()->push('user.items', 'item1');
$request->session()->push('user.items', 'item2');
$request->session()->save();
or try this
$items = Session::pull('items');
$items[] = $id;
Session::push('items', $items);
umm i think you used it wrong,
see the DOC
it says
Session::push('user.teams', 'developers');
user is the array and we gonna put a value developers to that array with teams key
so then you need to use it in your case as,
Session::push('items.id', $id);
OR if you need to maintain items as an array with default keys like 0,1,2,3... to put the ids, then items should be an array
so there should be a something like,
Session::put('items', []);
then you can use Session::push('items', $id);
if you need to push ids in to same array as you tried.

Session variable on refresh

I have laravel controller like this:
public function postSessionTopic() {
$article_id = Input::get('article_id', 0);
$comment_id = Input::get('comment_id', 0);
\Session::set('page_topic_id', $article_id);
\Session::set('page_comment_id', $comment_id);
\\comment - I have tried \Session::put too, but that doesn't change anything
}
I use it, when user click on a article. I print_r out my session variable in this controller and everything looks fine. But after that I refresh my page, and there I read value from session, and sometimes it load old value or doesn't load anything. I can't understand why, because in controller i can see, that correct value is saved!
In my page, i get that value like this:
\Session::get('page_topic_id', 0)
Probably you do something wrong. You should make sure that in both cases you uses exactly same domain (with or without www).
In this controller when you don't have any input you set to session variables 0. This can also be an issue if you launch this method when you don't have any input.
You could try with adding this basic route:
Route::get('/session', function() {
$page_topic = Session::get('page_topic_id', 1);
$page_comment = Session::get('page_comment_id', 1);
echo $page_topic.' '.$page_comment.'<br />';
$article_id = $page_topic * 2;
$comment_id = $page_comment * 3;
Session::set('page_topic_id', $article_id);
Session::set('page_comment_id', $comment_id);
});
As you see it's working perfectly (but you need to remove session cookie before trying with this path).
You get
1 1
2 3
4 9
8 27
and so on. Everything as expected
Answer was - two ajax at one time. Don't do that, if you store something in session.
The session in Laravel doesn't consider changes permanent unless you generate a response (and that's the result of using symphony as it's base). So make sure your app->run() ends properly and returns a response before refreshing. Your problem is mostly caused by a die() method somewhere along your code or an unexpected exit of PHP instance/worker.
This is probably not your issue but if you are storing your laravel session in the database their is a limit on how large that value can be. The Laravel session migration has a field called "payload" that is a text type. If you exceed the limit on that field the entire session gets killed off. This was happening to me as I was dynamically adding json model data to my session.
Schema::create('sessions', function (Blueprint $table) {
$table->string('id')->unique();
$table->text('payload');
$table->integer('last_activity');
});
How much UTF-8 text fits in a MySQL "Text" field?

CakePHP Pagination sort() on Related Models

I have two models: Plans and PlanDetails.
Relationship is: PlanDetails hasMany Plans. Plans belongTo PlanDetails.
In the PlanDetails view.ctp, I am pulling in related Plans.
I am trying to sort the Plans by ANY field (I've tried them all), and I cannot get it working. I assume I am overlooking something very simple.
Here is my base code:
PlanDetail >> view.ctp:
...foreach ($planDetail['Plan'] as $plan_edit) :
$class = null;
if ($i++ % 2 == 0) {
$class = ' class="altrow"';
}...
<?php echo $this->Paginator->sort('Plan ID', 'Plan.id'); ?>...
...<?php echo $plan_edit['id']; ?>
plan_details_controller.php:
...function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid plan detail', true));
$this->redirect(array('action' => 'index'));
}
$this->PlanDetail->recursive = 2; // To run the editable form deeper.
$this->set('planDetail', $this->PlanDetail->read(null, $id));
$this->set('plan', $this->paginate('Plan'));
}...
I should add, no errors are being thrown and the sort() arrows on the ID field are showing as expected, but the sort order DOES not change when clicked either way.
Sorry, I'm not able to comment on the question itself, but I've noticed that in your action, you set planDetail to be the PlanDetail record you read (with recursive set to 2), and then you set plan to be the result of the paginate call.
Then, in your view template, you're iterating over $planDetail's contained Plan association, like this:
foreach ($planDetail['Plan'] as $plan_edit):
But in order to get the sorting and pagination done, you need to be displaying the results of the paginate call i.e. iterate over the records contained in $plan.
Do a debug($plan) in your view template to see what results you get there and to see if the records' ordering changes when you sort by different fields.
Also, perhaps you're using syntax I'm not aware of, but if you simply call $this->paginate('Plan') in your controller, I don't know that you're going to get only the related Plan records for your particular PlanDetail record. (There's nothing tying the $id passed into your view action with the Plan records.) You might need to add some conditions to the paginate call, like so:
$this->paginate['Plan'] = array('conditions' => array('Plan.plan_detail_id' => $id));
$this->set('plans', $this->paginate('Plan'));
Here is what I did to solve this. Based on some helpful direction from johnp & tokes.
plan_details/view.ctp:
...$i = 0;
foreach ($plan as $plan_edit) : // note $plan here.
}...
In my plan_details_controller.php view action:
$conditions = array("Plan.plan_detail_id" => "$id");
$this->set('plan', $this->paginate('Plan', $conditions)); // note "plan" in the first argument of set (this is required to pass the results back to the view). Also. The $condition is set to return ONLY plans that match the plan_detail_id of id (on the plan_details table).
And in my view, in order to get my results (because I changed the array name), I had to change the way I was getting the values to:
$plan_edit['Plan']['modified'] // note I placed ['Plan'] in front of these calls as the array called for this to get the data...
Well until the next problem! SOLVED.

Resources