I have one to many relation tables. I want to insert child table data in array instead of rows.
Mobile.php
protected $fillable = ['mobile_id', 'mobile_name'];
public function models() {
return $this->hasMany(Model::class, 'mobile_id');
}
Model.php
protected $fillable = ['model_name', 'mobile_id'
];
public function model()
{
return $this->belongsTo(Mobile::class, 'mobile_id');
}
View
Mobile Name: <input type="text" name="mobile_name">
Models:
<input type="text" name="model_name[]">
<button class="add_model">Add Model</button>
Controller
public function create(Request $request, Mobile $mob){
$mob= new Mobile;
$mob->mobile_name = request('mobile_name');
for($i=0; $i < count(request('model_name')); $i++){
$models = new Model;
$models->model_name = request('model_name')[$i];
$mob->models()->save($models);
}
$mob->save();
}
It's creates a new row for each mobile models inserted. But I want those models inserted in a single column model_name in an array line.
I tried
for($i=0; $i < count(request('model_name')); $i++){
Size::create([
'model_name' => request('model_name')[$i],
'mobile_id' => $mob->id
]);
But it is also not working.
I think the problem is your schema table, because you need to achieve this first :
// Migrations
$table->json('model_name');
That way you can persist many model_name in one row using one array.
You should serialize the data before saving it in the database.Create the model instance outside the for loop.Here is the working code.
public function create(Request $request, Mobile $mob){
$mob= new Mobile;
$mob->mobile_name = $request('mobile_name');
$models = new Model;
$arr=[];
for($i=0; $i < count($request('model_name')); $i++){
array_push($arr, $request('model_name')[$i]);
}
serialize($arr);
$models->model_name =$arr;
$mob->models()->save($models);
$mob->save();
}
In the model.php, add the below code
protected $casts = [
'model_name ' => 'array',
]
Try this 100% working i have deployed .
foreach($request->model_name as $item => $value)
$data[$value]=array(
'mobile_name'=>$request->mobile_name,
'model_name'=>$value,
);
Mobile::insert($data); // Eloquent approach
Related
I try to save a morph relationship in my database, but when i try to save it I Have tow entry in every table use for the relation.
here is my client class
class Client extends Model
{
protected $guarded = [];
public function clientelle(){
return $this->morphTo();
}
}
my particulier class
class Particulier extends Model
{
protected $guarded = [];
public function client(){
return $this->morphOne(Client::class,'clientelle');
}
}
So when I try to save like that :
$particulier = new Particulier();
$particulier->nom = $request->nom;
$particulier->prenom = $request->prenom;
$particulier->save();
$particulier->client()->create(['telephone'=>$request->telephone,'adresse'=>$request->adresse,'email'=>$request->email]);
My database save two same recorde. Here is my problem.
So I have try diffrente thing to avoid it but I have error every time
delete $particulier->save(); but SQL error id don't exist
replace create([...]) by save([...]) or sync([...]) but don't work
Thank you in advance
So I have finally find a worst solution...
In your controller add int var and init it to 0 like that :
Private $checkDouble=0;
In place where you want save your relation create if block and put in all of your model save like that :
if($this->checkDouble==0) {
$this->checkDouble = $this->checkDouble + 1; //Increase your var value
$particulier = Particulier::create(['nom' => $request->nom, 'prenom' => $request->prenom]);
$particulier->client()->create(['telephone' => $request->telephone, 'adresse' => $request->adresse, 'email' => $request->email]);
}
And no more duplicate data
I know is really worst solution but I don't see any best solution ^^
I am working with laravel 5.5 to update entries. The problem is after changing the primary key 'id', which is elequoent default pk to 'project_id'. adding an item works fine but updating an item is not working properly. Here is the error I am getting.
Method save does not exist.
Here is my Model.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Project extends Model
{
protected $primaryKey = 'project_id';
public function user()
{
return $this->belongsTo(User::class);
}
public function tasks()
{
return $this->hasMany(Task::class);
}
}
Here is my controller function.
public function editProject($id){
$project = Project::where('project_id', $id)->firstOrFail();
$data = ["project_info" => $project];
return view('projects.edit')->with($data);
}
public function updateProject(Request $request){
$data = $request->all();
$validator = Validator::make($data, [
'project_title' => 'required',
'project_description' => 'required',
'project_start_date' => 'required',
'project_end_date' => 'required',
'project_status' => 'required',
]);
$response = [];
if ($validator->fails()){
$response["errors"] = [$validator->messages()->first()];
$response["success"] = false;
return json_encode($response);
}
else{
$project = Project::where("project_id", $request->input('project_id'))->get();
$project->project_title = $request->project_title;
$project->user_id = Session::get('user_id');
$project->project_description = $request->project_description;
$project->project_start_date = $request->project_start_date;
$project->project_end_date = $request->project_end_date;
$project->project_status = $request->project_status;
$project->save();
return redirect('/listProjects');
}
}
Using get() returns a collection. Despite the fact you are passing in a 'unique' ID, the project_id, it will still return a collection - the collection will simply have one element in it.
Subsequently, your code will not work as you have experienced, or at least not without a few changes to make $project reference the first element in the collection.
It's a quick fix though, just change this:
$project = Project::where("project_id", $request->input('project_id'))->get();
to this:
$project = Project::where("project_id", $request->input('project_id'))->first();
By using first(), eloquent will return the first element that matches the query and actually return the element (as opposed to a collection with one element) and so you can directly edit and save it.
Here is the solution I found.
$project_id = $request->input('project_id');
$project = Project::find($project_id);
$project->save();
You can find it by id using
Project::find($id);
Or get the first element like James said:
$project = Project::where("project_id", $request->input('project_id'))->first();
I have user input following the rules below;
public function rules()
{
return [
'phone_number' => 'required|array',
'amount' => 'required|string|max:4',
'phone_number_debit' => 'required|string|max:15',
];
}
I would want to save the data in a model Transaction. For the phone_number it is an array that could have one value or multiple. So that leaves for foreach loop.
This is what I want to achieve, save different rows determined by the number of records in the array.
$transaction = new Trasaction();
$transaction->phone_number = $req->phone_number; //Value in the array
$transaction->amount = $req->amount;
$transaction->phone_number_debit = $req->phone_number_debit;
$transaction->save();
Save diffrent records according to the records in the phone_number array.
However I can not think of a way to achieve this.
Anyone?
try this :
$data = request(['amount', 'phone_number', 'phone_number_debit']);
foreach($data['phone_number'] as $phone_number) {
Trasaction::create([
'amount' => $data['amout'],
'phone_number' => $phone_number,
'phone_number_debit' => $data['phone_number_debit']
]);
}
make sure in your Trasaction modal you've set to fillable property like this :
class Trasaction extends Model
{
protected $fillable = ['amount', 'phone_number', 'phone_number_debit'];
}
There are many ways to do this, in a nutshell:
collect(request('phone_number'))->each(function ($phone) use ($req) {
$transaction = new Trasaction();
$transaction->phone_number = $phone; // element of the array
$transaction->amount = $req->amount;
$transaction->phone_number_debit = $req->phone_number_debit;
$transaction->save();
});
TL;DR
One-to-Many Relationship
In order to get a better code, you can create a transaction_phones table, creating a one-to-many relationship.
You'll create a TransactionPhone model and add this:
public function transaction()
{
return $this->belongsTo(Transaction::class);
}
The TransactionPhone migration:
Schema::create('transaction_phones', function (Blueprint $table) {
$table->increments('id');
$table->integer('transaction_id');
$table->string('phone_number');
$table->timestamps();
});
In your Transaction model you'll have the inverse:
public function phones()
{
return $this->hasMany(TransactionPhone::class);
}
public function addPhone($phone)
{
return $this->phones()->create(['phone_number' => $phone]);
}
And in you Controller:
$transaction = Trasaction::create(request()->only('amount', 'phone_number_debit'));
collect(request('phone_number'))->each(function ($phone) use ($transaction) {
$transaction->addPhone($phone);
});
I hope this answer can help you.
Update Method:
public function update(UserUpdateRequest $request, Users $uzytkownik)
{
$this->authorize('update', $uzytkownik);
if ( $uzytkownik->update([
'birth' => $request->birth,
'sex' => $request->sex,
'about' => $request->about,
]) )
{
return 1;
}
return 0;
}
On update here in page 1 appears. Like it did the thing.
But in db nothing has changed.
$uzytkownik is proper user, and
This is the dd($uzytkownik);
And below dd($request->birth.'---'.$request->sex.'---'.$request->about); which shows proper inputs
Why it doesn't work properly?
As per the documentation
Mass Assignment
You may also use the create method to save a new model in a single line. The inserted model instance will be returned to you from the method. However, before doing so, you will need to specify either a fillable or guarded attribute on the model, as all Eloquent models protect against mass-assignment by default.
You need to make sure $fillable or $guarded is correctly set otherwise changes may not be persistant.
You can do what you want like this too:
public function update(UserUpdateRequest $request, Users $uzytkownik)
{
$this->authorize('update', $uzytkownik);
$uzytkownik->birth = $request->birth;
$uzytkownik->sex = $request->sex;
$uzytkownik->about = $request->about;
if ( $uzytkownik->save() )
{
return 1;
}
return 0;
}
I have a master table jobs with multiple location in separate table job_location. Now I am not able to update/delete, if extra rows found from job_location. Now why I am saying DELETE is because sync() did this, but it's related to many-to-many relation. I am new to laravel, just trying to get eloquent approach to achieve this, otherwise deleting all rows and inserting can be done easily OR updating each and delete remaining is also an option but I wonder Laravel has something for this.
In every request I get multiple job locations(with unchanged/changed city,phone_number,address) which is creating trouble.
Some codeshots:
Model: [Job.php]
class Jobs extends Model
{
protected $fillable = [
'job_id_pk', 'job_name','salary'
];
public function joblocation() {
return $this->hasMany('\App\JobLocation', 'job_id_fk', 'job_id_pk');
}
}
Model:[JobLocation.php]
class JobLocation extends Model
{
protected $fillable = [
'jobl_id_pk', 'job_id_fk','city', 'address', 'phone_number'
];
public function job() {
return $this->belongsTo('\App\Jobs', 'job_id_fk', 'job_id_pk');
}
}
Controller:[JobController.php]
function jobDetail() {
if($params['jid']) {
// update
$obj = \App\Jobs::find($params['jid']);
$obj->job_name = $params['name'];
$obj->salary = $params['salary'];
$obj->save();
} else {
// create new
$data = array(
'job_name' => $params['name'],
'salary' => $params['salary'],
);
$obj = \App\Jobs::create($data);
}
// don't bother how this $objDetail has associative array data, it is processed so
foreach ($params['jobLocations'] AS $key => $objDetail) {
$jobLoc = new \App\JobLocation;
$jobLoc->city = $objDetail['city'];
$jobLoc->phone_number = $objDetail['phone_number'];
$jobLoc->address = $objDetail['address'];
$jobLoc->job()->associate($obj);
$obj->jobLoc()->save($jobLoc);
}
}
In this approach I am able to save all job locations, but I am using same function to update also. Please tell how I can update jobLocations if present. I am ok to loose previous entries, but it would be good if previous gets updated and new get entered OR if we have extra entries they get deleted. I know sounds weird but still guide me a way.
Yea, you cannot use the same function, do this
$jobs = \App\Jobs::find($params['jid']);
foreach ($params['jobLocations'] as $key => $objDetail) {
$joblocation = $jobs->joblocation->where('jobl_id_pk', $objDetail['some_id'])->first();
//here update you job location
$joblocation->save();
}
Something like this:
Controller:[JobController]
public function jobDetail() {
if( !empty($params['jid']) ) {
// update
$job = \App\Jobs::find($params['jid']);
$job->job_name = $params['name'];
$job->salary = $params['salary'];
$job->save();
} else {
// create new
$data = array(
'job_name' => $params['name'],
'salary' => $params['salary'],
);
$job = \App\Jobs::create($data);
}
$locationDetails = !empty($params['jobLocations']) ? $params['jobLocations'] : [];
$jobLocations = array_map(function($location) use($job) {
$location = array_merge($location, [ 'job_id_fk' => $job->job_id_pk ]);
return \App\JobLocation::firstOrNew($location);
}, $locationDetails);
$job->jobLocations()->saveMany($jobLocations);
}