doctrine - Inserting records in many to many relationship table - php

I have two models Property and Amenity the relationship between them is many to many. the reference class is PropertyAmenity when i want to insert single record into one model it is easy for me.
to insert into Property
$property = new Property();
$property->serial = 'SER09088';
$property->title = 'Some title';
$property->save();
and to insert record into Amenity it is
$amenity = new Amenity();
$amenity->name = 'Swimming Pool';
$amenity->save();
what i want to do is add existing amenities to Property the record of which holds in reference class PropertyAmenity for example something like.
$property = new Property();
$property->serial = 'SER09088';
$property->title = 'Some title';
$property->PropertyAmenity->amenity_id[] = 1;
$property->save();
when i try the above code it gives me following exception
Add is not supported for PropertyAmenity
the situation is i gather collective information from a form, from a user. for example a user inputs all the value related to Property and select existing Multiple Amenities from the form and submit. i need to save Property in property table and the selected amenities in property_amenity table which consist of two columns property_id and amenity_id, how do insert this value in doctrine?

After digging around a little bit, i found the solution myself and as expected, it is so easy to implement. the only change i had to do was.
From this
$property->PropertyAmenity->amenity_id[] = 1;
To
$property->PropertyAmenity[]->amenity_id = 1;
$property->PropertyAmenity[]->amenity_id = 3;
$property->PropertyAmenity[]->amenity_id = 5;
and it works, hope it helps someone :)

Related

PHP, Laravel - Concatenation with String to Model

Is is possible to concatenate a string to Model? The below doesn't seem to work.
I have Car Model and Train Model. Vehicle will be either Car or Train.
$vehicle = 'Car';
$result = $vehicle::where('model', $value)->count() > 0;
The above code exists the following error.
Symfony\Component\Debug\Exception\FatalThrowableError: Class 'Car' not found in file
How can I concatenate? Is it possible?
I think this is the closest to what you need,
you don't have to import anything since you have a dynamic value. (If you have 10 possible models you will have to import all of them)
So you should do something like this
$model = "Car";
$modelsPath = "\\App\\Models\\";
$className = $modelsPath.$model;
// if you need an instance you do this
// $instance = new $className;
$result = $className::where('model', $value)->count() > 0;
dd($result);
What i usually do is create a config file that contains an array of all possibilities where they key is the type (Car,Bus,Train in ur example)
And then i get the value using the key which is the input (car) and the model path will be in the config! that way you can swap it later easy and attach more conditions related to that type of model etc.
I hope this makes sense
Regards
use App\Car; //place this at the top of your page. Make sure the model exists
Yes, you can concatenate a model depending upon the condition. Below, I have added a workable code to implement.
Import both model.
//use App\Car;
//use App\Train;
$isCar = true; // boolean condition to check whether it is a car or train
$classVariable = null;
if ($variable) {
$classVariable = new Car();
}else{
$classVariable = new Train();
}
$result = $classVariable->where('model', $value)->get();
//this will provide you a car model query
dd($result);
Better Approach
A better approach will be to use a Vehicle model and Vehicle Type.
Add a vehicle_type_id in the vehicles table.
So whenever you need to retrieve car types, you can use
//Suppose vehicle_type_id for car is 1
$carVehicle = Vehicle::where('vehicle_type_id', 1)->get();
//Suppose vehicle_type_id for train is 2
$trainVehicle = Vehicle::where('vehicle_type_id', 2)->get();
It's Possible
use App\Car;
use App\Train;
/* Here You can now set Model name dynamically*/
$vehicle = 'Car';
$result = $vehicle::where('model', $value)->count() > 0;
I think one approach can as below:
$vehicle = Car::class; //this will dynamically add full namespace of Car class.
$result = $vehicle::where('model', $value)->count() > 0;

Update a Relationship Model with one Line - Laravel

I have a massive edit page and the values are taken from 4 tables. I have them all in a object and sorted which ones go where. Although when I call my main model, can I update its relationship by passing in the object or array?
Main Model
$officiant = Officiant::find($id);
Its relationship is the "detail" and "profile"
Example:
$officiant->fname = $request->fname;
$officiant->lname = $request->lname;
$officiant->phone = $request->phone;
$profile = new \StdClass();
$profile->gender = $request->gender;
$profile->profile = $request->profile;
$detail = new \StdClass();
$detail->street = $request->street;
$detail->city = $request->city;
I can update officiant by passing it like this
$officiant->update(array ($officiant));
Although, can I update the detail one by doing something similar, as in
$officiant->detail->update(array ($detail));
$officiant->profileupdate(array ($profile));
If you are updating via a relation ship it should be
$officiant->detail()->update(array ($detail));
Using ->detail() instead of ->detail sends a query builder instance that can be chained with update().

Update data into table from dynamically created input field

I have 2 models Tour.php
public function Itinerary()
{
return $this->hasMany('App\Itinerary', 'tour_id');
}
and
Itinerary.php
public function tour()
{
return $this->belongsTo('App\Tour', 'tour_id');
}
tours table:
id|title|content
itineraries table:
id|tour_id|day|itinerary
I have used vue js to create or add and remove input field for day and plan dynamically. And used the following code in tour.store method to insert into itineraries table:
$count = count($request->input('day'));
$temp_day = $request->input('day');
$temp_itinerary = $request->input('itinerary');
for($i = 0; $i < $count; ++$i)
{
$itinerary = new Itinerary;
$itinerary->tour_id = $tour->id;
$itinerary->plan = $temp_itinerary[$i];
$itinerary->day = $temp_day[$i];
$itinerary->save();
}
And was successful in inserting the records.And applied same code in tour.store method. Instead of updating the rows, it inserted new rows to the table. What would be the best solution for this ?
For updation try this code
$itinerary = Itinerary::find($tour_id);
$itinerary->plan = $temp_itinerary[$i];
$itinerary->day = $temp_day[$i];
$itinerary->save();
The way you are using is to insert/create new records. To update you can use.
Itinerary::find($tour_id)->update(
['column_name'=> value]
);
Where find method takes a primary key of the table.
This will update your existing record. You can update as many columns as you want just pass in array update takes. You can also use save method as mentioned in other answer.
Check Laravel Update Eloquent
EDIT
$iterneary = Itenerary::where('tour_id', $tour_id)->first();
Now you can update this iterneary object to whatever you want.
this is how i did it. First saved all the tours in $tours[] array.
foreach($tours as $tour) {
$itinerary->tour()->updateOrCreate(['id'=> $tour['id']],$tour);
}
updateOrCreate because you may need to add new tours while updating. I know this doesnt answer your issue exactly but this could atleast give you an idea.

Laravel 5.2 updated table now model wont work

I updated my notes table with 4 new columns: classification, pod, sampled, followup.
I would update my model like so (which still works like this):
$note->account_id = $account->id;
$note->name = $request->input('account-note-title');
$note->description = $request->input('account-note-description');
$note->save();
But if I try and post to the new columns it fails.
$note->account_id = $account->id;
$note->name = $request->input('account-note-title');
$note->description = $request->input('account-note-description');
$note->classification = $request->input('account-note-classification');
$note->pod = $request->input('account-note-pod');
$note->sampled = $request->input('account-note-samplebrand');
$note->followup = $request->input('account-note-followup-date');
$note->save();
Do I have to refresh the model or anything?
You can create new value using laravel Create methode like below
ModelName::create($request->all())
In this case you have to put your all input field in the $fillable variable of MODEL.
You can update item using the following method
$model = findOrFail($id)
$model->update($request->all())

Duplicate an AR record & re-insert this into the database

I have a AR model that I am trying to duplicated but just need to manually change the foreign key.
$_POST['competition_id'] = 99;
$prizes = CompetitionPrizes::model()->findAll('competition_id =:competition_id',array(':competition_id'=> $_POST['competition_id']));
This query basically queries the prizes table and gets all the rows for a particular competition. With the prizes object I would like to basically re-insert/duplicate the same information except the competition id which I want to manually set.
I did something similar for an AR object that basically only has one row and that worked well, however in this instance as a competition can have more than one prize this same code won't.
// My existing code for duplication process
$obj = Competitions::model()->find('competition_id=:competition_id', array(':competition_id' => $post['competition_id']));
$clone = clone $obj;
$clone->isNewRecord = true;
unset($clone->competition_id); // i want to remove this so it is auto inserted instead via the db
$clone->save();
This works great - how would I modify this on a 'collection' of prizes and have this duplicated into the database while setting my own 'competition_id' value.
Note - i'm to new to Yii, so please let me know if I have made any obvious errors/bad practice
Cloning won't work. You need to assign the attributes to a new object:
$obj = Competitions::model()->find('competition_id=:competition_id', array(':competition_id' => $post['competition_id']));
$clone = new Competitions;
$clone->attributes = $obj->attributes;
$clone->save();
If a more generic way of duplicating a Model / ActiveRecord in Yii2 Framework is required, you might use this solution:
$copy = clone $model;
$copy->isNewRecord = true;
foreach ($model->getPrimaryKey(true) as $field => $value) {
unset($copy->{$field});
}
$copy->save();
GitHub issue discussion about duplicate models: https://github.com/yiisoft/yii2/issues/7544#issuecomment-77158479
The answer for my problem although Michiel above helped me out - alternatively if you wouldn't mind adding another answer i'll give you the accepted answer.
foreach($models as $model)
{
$clone = new Competitions;
$clone->attributes = $model->attributes;
$clone->competition_id = '123' // custom var i am setting manually.
$clone->save();
}
How about (yii2 syntax):
$model=Competitions::findOne([':competition_id' => $post['competition_id']]);
$model->id = null;
$model->isNewRecord = true;
$model->save();

Categories