Laravel 5 dynamic input fields saving relation to database - php

I have a dynamic input field called name="step[]". When submitting the form and displaying the $request->step using dd, I get this:
array:3 [
0 => "Test Step 1"
1 => "Test Step 2"
2 => "Test Step 3"
]
So it is an array. Now, when I want to insert the data using:
$project = new Project;
$project->name = $request->name;
$project->save();
$project->steps()->saveMany($request->step);
I am getting this error:
Argument 1 passed to Illuminate\Database\Eloquent\Relations\HasOneOrMany::save() must be an instance of Illuminate\Database\Eloquent\Model, string given
Project Model:
public function steps()
{
return $this->hasMany('App\Step');
}
My goal is to create a new Project and save it to the database, and save all steps in my Step table. So each Project hasMany steps. Not sure why I am getting the above error though, since I am passing an array?

I usually realize using a foreach loop. Your relation method seems to look OK. Does this work?
foreach($request->steps as $step) {
$project->steps()->create(['step' => $step]);
}

Did you try using the attach method?
$project->steps()->attach($resquest->input('steps'));

Related

How do i resolve Call to a member function only() on array error

I want to use laravels FormRequest to validate before updating some fields. This works fine if i just use:
User::find($application->userid)->fill($request->only('first_name'...
but the request also contains sub array ($request->programmeData).
array:2 [▼
"programme_id" => 5
"programme_title" => "some programme title"
]
if i try access that the same way i get 'Call to a member function only() on array':
Course::find($application->userid)->fill($request->programmeData->only('programme_id...
I've tried a handful of things, but not sure best way to go with this?
Update
I'm now using a foreach loop to save two items in the array. the example below saves the second value for both user_ids. any reason this isn't saving the first value for the first user_id?
foreach ($request->programmeData['userProgrammes'] as $key=>$userProgrammes) {
Course::where('application_id', $application->id)->get()[$key]->fill(Arr::only($request->programmeData['userProgrammes'][$key], ['programme_id']))->save();
}
but nothing updates. Any ideas on this one?
You can use Array::only() helper for this:
foreach ($request->programmeData['userProgrammes'] as $key=>$userProgrammes) {
Course::where('application_id', $application->id)->first()->fill([
$key => Arr::only($request->programmeData['userProgrammes'][$key], ['programme_id'])
])->save();
// or
$course = Course::where('application_id', $application->id)->first()
$course->$key = Arr::only($request->programmeData['userProgrammes'][$key], ['programme_id']);
$course->save();
}
//Arr::only($request->programmeData, ['programme_id', ...]);

How to get the correct Id parameter after saving on Laravel

I have an SQL server DB currently working on a C# site, so I created a Laravel Project from scratch to use that DB. Everything is working and I can consult and write data on it, but the problem that I have is when I create a new object into a table I'm not getting the correct id parameter after the new Class function.
This is my Controller:
$softwareRequest = new SoftwareRequest;
$softwareRequest->OwnerManager = $request->input('contactApplicationManager');
$softwareRequest->TestorName = $request->input('contactTesterRequestedBy');
$softwareRequest->TestorPhone = $request->input('contactTesterPhone');
$softwareRequest->TestorEmail = $request->input('contactTesterEmail');
$softwareRequest->save();
if I DD() the variable $softwareRequest I get:
#attributes: array:5 [▼
"OwnerEmail" => "test#test.com"
"TestorName" => "Testor Name"
"TestorPhone" => "3456787455"
"TestorEmail" => "test1#test.com"
"Id" => 57980
the Id on the database is set to Id (the I in Uppercase) instead of id but the Id parameter I get after saving is not the correct one (not even close), once I go to the DB to check manually, it did stored the data with the correct Id number, since I'm using eloquent and I created the models for each table, how can I get the correct Id parameter for the new saved data right after I ->save() ? I need to get the Id right after saving because I need to use it to store something else on another table.
This is what the model has:
protected $table = 'SoftwareRequest';
protected $primaryKey = 'Id';
public $timestamps = false;
I put primary key as Id since that's the way it is set in the DB, if I take away the line
protected $primaryKey = 'Id';
I get the same but id with lowercase
#attributes: array:5 [▼
"OwnerEmail" => "test#test.com"
"TestorName" => "Testor Name"
"TestorPhone" => "3456787455"
"TestorEmail" => "test1#test.com"
"id" => 57981
but again, that's not even close on the correct Id it should get, the increment next number is 5917, I think the problem might be more on that the tables are hard coded on the models, any idea?
Try this:
$softwareRequest =SoftwareRequest::create([
'OwnerManager' = $request->input('contactApplicationManager'),
'TestorName' = $request->input('contactTesterRequestedBy'),
'TestorPhone' = $request->input('contactTesterPhone'),
'TestorEmail' = $request->input('contactTesterEmail'),
]);
Then:
dd($softwareRequest);

UpdateOrCreate Model Object

I am using Laravel 5.5 and I am declaring my model object the following:
$product = new product();
$product->name = $coinArr[$key];
$product->symbol = $symbolArr[$key];
$product->current_price = $priceArr[$key];
///save image to public folder
$fileName = basename($imgArr[$key]);
Image::make($imgArr[$key])->save(public_path('images/' . $fileName));
$product->asset_logo = $fileName;
//$product->updateOrCreate();
App/Product::updateOrCreate($product);
If the product does not exist in the database I would like to create it else just update it.
I tried the following two ways to use the updateOrCreate method. However, I receive the following error for App/Product::updateOrCreate($product);:
Type error: Too few arguments to function Illuminate\Database\Eloquent\Builder::updateOrCreate(), 0 passed in C:\Users\admin\Desktop\Coding Projects\laravel_proj\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php on line 1455 and at least 1 expected
And the following error for $product->updateOrCreate();:
Type error: Too few arguments to function Illuminate\Database\Eloquent\Builder::updateOrCreate()
Any suggestions how to use updateOrCreate with my model object?
I appreciate your replies!
When you use updateOrCreate, you need to choose which attributes are used to determine if the product exists already. The function takes 2 arrays:
product::updateOrCreate([
'name' => $coinArr[$key] //Laravel will check if this model exists by name
],[
'symbol' => $symbolArr[$key] //if exists, will update symbol. if doesnt exist, will create new with this name and symbol
]);
That's not how the updateOrCreate() method works. In the first parameter you put an array with search conditions. If you want to search existing route by name for example, the correct syntax will be:
Product::updateOrCreate(
[
'name' => $coinArr[$key]
],
[
'symbol' => $symbolArr[$key],
'current_price' => $symbolArr[$key],
'asset_logo' => $fileName
]
);
The second parameter is array for creating a new object.
https://laravel.com/docs/5.5/eloquent#other-creation-methods

Laravel 5 - How to add multiple parameters to laravel array for db insert?

I have an array of 3 companies, which need to be inserted into the db but with 2 additional parameters added to them.
$companyList = [{"name": "apple", "founder": "steve"},
{"name": "google", "founder": "larry"},
{"name": "facebook", "founder": "mark"},
];
Need to append these 2 parameters for each company (issue is in this step):
$companyListFinal = [];
foreach ($companyList as $company) {
$companyListFinal[] = array_add($company,['keyAppend1' => 'key 1 appended',
'keyAppend2' => 'key 2 appended'];
}
The final step is to insert the company list with the appended values into the DB:
DB::table('companies')->insert($companyListFinal);
I can't seem to be able to append the 2 new parameters to create the final array to insert:$companyListFinal
What's the correct way to add the parameters to each company so they are all inserted at bulk?
You need to use array_merge instead of array_add
Try using array_push() instead on array_add(). That should do the job.

does sfWidgetFormSelect provide a string or an int of the selected item?

I'm having an annoying problem. I'm trying to find out what fields of a form were changed, and then insert that into a table. I managed to var_dump in doUpdateObjectas shown in the following
public function doUpdateObject($values)
{
parent::doUpdateObject($values);
var_dump($this->getObject()->getModified(false));
var_dump($this->getObject()->getModified(true));
}
And it seems like $this->getObject()->getModified seems to work in giving me both before and after values by setting it to either true or false.
The problem that I'm facing right now is that, some how, sfWidgetFormSelect seems to be saving one of my fields as a string. before saving, that exact same field was an int. (I got this idea by var_dump both before and after).
Here is what the results on both var dumps showed:
array(1) {["annoying_field"]=> int(3)} array(1) {["annoying_field"]=>string(1)"3"}
This seems to cause doctrine to think that this is a modification and thus gives a false positive.
In my base form, I have
under $this->getWidgets()
'annoying_field' => new sfWidgetFormInputText(),
under $this->setValidators
'annoying_field' => new sfValidatorInteger(array('required' => false)),
and lastly in my configured Form.class.php I have reconfigured the file as such:
$this->widgetSchema['annoying_field'] = new sfWidgetFormSelect(array('choices' => $statuses));
statuses is an array containing values like {""a", "b", "c", "d"}
and I just want the index of the status to be stored in the database.
And also how can I insert the changes into another database table? let's say my Log table?
Any ideas and advice as to why this is happen is appreciated, I've been trying to figure it out and browsing google for various keywords with no avail.
Thanks!
Edit:
ok so I created another field, integer in my schema just for testing.
I created an entry, saved it, and edited it.
this time the same thing happened!
first if you what the status_id to be saved in the database, you should define your status array like this:
{1 => "a", 2 => "b", 3 => "c", 4 => "d"}
So that way he know that 1 should be rendered like "a" and so on. Then, when saving, only the index should be saved.
About saving in another database, my advise is to modify the doSave method defined by the Form class yo match your needs. I only know how Propel deals with it, maybe this could help:
the doSave method dose something like this:
protected function doSave($con = null)
{
if (null === $con)
{
$con = $this->getConnection();
}
$old = $this->getObject()->getModifiedValues($this);//Define this
$new_object = new Log($old);//Create a new log entry
$new_object->save($con));//save it!
$this->updateObject();
$this->getObject()->save($con);
// embedded forms
$this->saveEmbeddedForms($con);
}
Hope this helps!
Edit:
This is an example extracted from a model in one of my applications and its working ok:
Schema:
[...]
funding_source_id:
type: integer
required: true
[...]
Form:
$this->setWidget('funding_source_id', new sfWidgetFormChoice(array(
'choices' => array(1 => 'asdads', 2 => '123123123' , 3 => 'asd23qsdf'),
)));
$this->setValidator('funding_source_id', new sfValidatorChoice(array(
'choices' => array(1 => 'asdads', 2 => '123123123' , 3 => 'asd23qsdf'),
'required' => true
)));
About the log thing, that could be quite more complex, you should read the current implementation of the doSave method in the base form class, currently sfFomrObject on Symfony1.4., and when and how it delegates object dealing with modified values.
Okay,
It turns out I forgot to do a custom validator to use the array key instead.

Categories