Laravel 8 save integer into null DB column - save vs update - laravel-8

I'm having an interesting issue where Laravel's save() does not replace null values in database, while the update() does. I also tested by manually changing null to 1 and afterwards the save() started updating the column. I am using save() throughout the project and would prefer that it stays that way or that at least I understand the problem before I go changing the code.
Migration (all codes will be partial extracts for brewity):
$table->foreignId('checklist_id')->nullable()->constrained('checklists')->onUpdate('cascade')->onDelete('cascade');
$table->foreignId('action_id')->nullable()->constrained('actions')->onUpdate('cascade')->onDelete('cascade');
Model (added the checklist_id and action_id for testing, otherwise they are not here):
// test
protected $fillable = [
'checklist_id',
'action_id',
];
protected $casts = [
'checklist_id' => 'integer',
'action_id' => 'integer',
];
// actual
protected $fillable = [
];
protected $casts = [
];
Controller:
public function update(UpdateWorkOrderRequest $request, WorkOrder $workOrder)
{
$response = $workOrder->save($request->all());
}
Form submission (from Chrome):
------WebKitFormBoundary73Z4wzsmsGcgOOAM
Content-Disposition: form-data; name="checklist_id"
1
------WebKitFormBoundary73Z4wzsmsGcgOOAM
Content-Disposition: form-data; name="action_id"
1
dd($request->all()):
array:2 [▼
"checklist_id" => "1"
"action_id" => "1"
]
The fields checklist_id and action_id are null after using save(), but they do get updated using update(). It's also working if I do this:
$workOrder->checklist_id = $request->checklist_id;
$workOrder->action_id = $request->action_id;
$workOrder->save();
I opted for save() to write less code instead of above example and because from docs I presume I can use save() when assigning data from $request, like here: https://laravel.com/docs/9.x/eloquent#updates

As discussed in the comments, you're trying to use model->save(attributes).
The save function does not provide any parameters for this. (docs).
You have two options, either use the model->update function (docs):
$workOrder->update($request->all());
Or use the model->fill (docs) function in combination with model->save like so:
$workOrder->fill($request->all())->save();

Related

how to append user input to Http get request in Laravel 9

Thank you in advance for taking the time to read through my question.
I'm upgrading an old project from Laravel 8 to Laravel 9
in laravel 8 i was able to append user input to a get request like this :
public function fetch(Request $request)
{
$userInput = $request->input();
$response = Http::withHeaders(
[
"x-rapidapi-host"=> "some.api",
"x-rapidapi-key"=> "**************",
]
)->get("https://some.api.com",$userInput);
$data = json_decode($response,true);
return view('view',compact('data'));
}
but when i try to do the same process in Laravel 9 i'm getting an error:
Invalid request
edit: (using dd() to show more error details about the response I'm getting)
array:4 [▼ // app\Http\Controllers\apiController.php:29
"searchType" => "Title"
"expression" => null
"results" => []
"errorMessage" => "Invalid request. See more information at https://theapiI'mUsing.com/api#/{lang?}/API/Search/{expression} - Search APIs: Search, SearchTitle, SearchName, SearchEpisod ▶"
]
I'm not able to send the data to the controller i guess? expression is showing null
although I was able to accomplish my goal using the same code in laravel 8
I have tried to append the input like this:
$response = Http::get("https://some.api.com/apiKey", [
'input' => $userInput,
]);
but also got the same error!
Invalid request
edit:
I have Also tried to concatenate the url with the user input
but got this error:
Array to string conversion
What is the proper way to append user input to a get request in Laravel 9?

Laravel Excel: how to have all zeroes printed in a exported csv?

I'm exporting to csv using Laravel Excel.
I'm creating the out value as
'amount' => number_format(-$ai->final_invoice_amount, 2, ".", "")
But, for example for 204.00, in the exported csv I got only 204, without dot and leading zeroes.
I know that it's a valid number for a computer; but our client has a strict parser and it wants a 204.00 value.
I tried, but not works, to add an explicit cast to string, but it's useless because number_format outputs a string in any case
'amount' => (string)number_format(-$ai->final_invoice_amount, 2, ".", "")
Laravel Excel's Events give you access to PHPSpreadSheet under the hood.
https://docs.laravel-excel.com/3.1/exports/extending.html#events
With Events, you can apply the desired formatting to a cell or group of cells. It's easier to demonstrate than explain, so I have created a simple example.
<?php
namespace App\Export;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\BeforeSheet;
class SampleExport implements FromCollection, WithEvents
{
public function collection()
{
return collect([
[
'id' => 1,
'amount_1' => 100,
'amount_2' => 75.20,
'amount_3' => -23.10,
],
[
'id' => 2,
'amount_1' => -60,
'amount_2' => 50.40,
'amount_3' => 110,
],
]);
}
public function registerEvents(): array
{
return [
BeforeSheet::class => function (BeforeSheet $event) {
// format columns B-D to two decimal places
$event->sheet
->getDelegate()
->getStyle('B:D')
->getNumberFormat()
->setFormatCode('0.00');
},
];
}
}
This is the resulting CSV as output to a file.
"1","100.00","75.20","-23.10"
"2","-60.00","50.40","110.00"
NOTE: The values being formatted MUST BE A NUMBER TYPE! Attempting to format strings will not work.

Flutter Printing Package: Create pdf table with loop

I want to create a pdf document with the package 'pdf'. The example on the dart - page is working fine: https://pub.dev/packages/pdf#-example-tab-
You can see that the table is static. I want to create a dynamic table in the pdf document.
The columns will be constant, but the rows have to be dynamic.
I have tried to insert a for() - loop.
The syntax is not correct.
pdfWidget.Table.fromTextArray(context: context, data: <List<String>> [
<String>['Date', 'PDF Version', 'Acrobat Version'],
//.....
//more Strings here.....
]),
I ran into the same issue.
This seemed to work for me.
pdf.addPage(
MultiPage(
build: (context) => [
Table.fromTextArray(context: context, data: <List<String>>[
<String>['Msg ID', 'DateTime', 'Type', 'Body'],
...msgList.map(
(msg) => [msg.counter, msg.dateTimeStamp, msg.type, msg.body])
]),
],
),
);
where my msgList object was a custom List, ie: List<SingleMessage>
There are several ways to do it, I prefer to fill the List separately, like:
List<List<String>> salidas = new List();
salidas.add(<String>['Title1','Title2', ... , 'Title n']);
for(var indice=0;indice<records.length;indice++) {
List<String> recind = <String>[
records[indice].Stringfield1,
records[indice].Stringfield2,
...,
records[indice].Stringfieldn
];
salidas.add(recind);
}
...
fpdf.Table.fromTextArray(context: context,data: salidas),

Yii Change field name

I want to rename the field. Code is here
[['name'], 'unique', 'message' => 'This Make already exists'],
output
[
{
"field": "name",
"message": "This Make already exists"
}
]
how i change field? Result
"field" : "make"
Using fields(). In your model override fields() function as follows:
public function fields()
{
return['make'=>'name'];
}
This will change the name of the field from name to make but your name field will be the only field returned. You can do all the tricks you want to append to the fields returned, or change them using this function though. To know more about fields check: http://www.yiiframework.com/doc-2.0/yii-base-model.html#fields()-detail

Backbone.js and ActiveRecord

This is a Noob question regarding Backbone.JS and ActiveRecord.
I'd be grateful for a pointer on how to debug this.
I'm trying to use Backbone.Js code to create a "Trainer" object, which has a single attribute, "name" (a string).
The front end of the application is Ruby on Rails. There is a data migration for the Trainer table.
In trainers controller:
def create
document = Trainer.create! params[:trainer]
render :json => document
end
Now, in app/assets/javascripts/backbone/views/trainers/new_view.js:
Gym.Views.Trainers.NewView = Backbone.View.extend({
el : 'div.trainer_form',
template: JST['backbone/templates/trainers/new_template'],
model : new window.Gym.Models.Trainer({}),
initialize: function() {
this.document = this.options.user;
Backbone.Validation.bind(this, {
invalid: function(view, attr, error) {
$("form#new-trainer .errors ul").append("<li>" + error + "</li>")
}
});
this.render();
},
render : function() {
$(this.el).html(this.template({trainer:this.model.toJSON()}));
return this
},
events : {
"click input#submit_button" : 'create_trainer'
},
create_trainer : function(event) {
event.preventDefault()
params = $("form#new-trainer").formParams()
params['user_id'] = Gym.currentUser.userId
this.model.save(params, {success : function(model, response) {
Gym.trainers.add(model)
Objects.views.selectTrainer.render()
Gym.current_trainer = model
$("select#trainer_selector").val(Gym.current_trainer.get('id'))
Objects.views.new_trainer.model = new Gym.Models.Trainer()
Objects.views.new_trainer.render()
}
});
Now, I can see in the Rails log that I'm getting to the controller:
Started POST "/trainers" ...
Processing by TrainersController#create as JSON
Parameters: {"name"=>"Lori Stevens", "user_id"=>1, "trainer"=>{}}
However, when it gets to the SQL, I see this:
[1m^[[36mSQL (0.4ms)^[[0m ^[[1mINSERT INTO `trainers` (`created_at`, `name`, `updated_at`, `user_id`) VALUES ('2012-11-07 20:33:09', NULL, '2012-11-07 20:33:09', NULL)^[[0m
The parameter 'name' - which comes from the template, and is the attribute of the Trainer object- is not getting to the database, even though the parameter "name" is set in the JSON.
I'd appreciate a pointer on how to debug this - clearly I am not understanding how Backbone.js and ActiveRecord are connected.
The Controller takes the request from your browser and puts the data into ActiveRecord:
def create
document = Trainer.create! params[:trainer]
...
end
But then you see request in the log, params[:trainer] equals the empty hash {}
You can either change the javascript that it creates json with a hash like
{ 'trainer': {'name' : 'Lori stevens', ... }}
I don't know how easy this in backbone.
Or you can change your controller that it gets the values out of the hash and constructs an new hash for your trainer model, like it is:
gotten_name_from_json = params['name']
...
document = Trainer.create!(
{:name => gotten_name_from_json, :town => gotten_twon_from_json})
I made this verbose to show that using this you can translate what ever json comes in, even when it comes from third parties where you can not control the format.