'Laravel - Best practice for saving model with related model
Initial setting / premise
I'm trying to figure out what would be the best practice for handling a saving of parent and child model with single controller-action, but handling saving on model-level.
I have an "form"-object which has related model "json_object". This object is passed to controller with AJAX:
form: {
id: 12,
title: "something",
json_object_id: 223, // <-- exists within form -table
json_object: { id: 223, description: 'something else' }
}
Both are represented on database on their own tables and have their own class models. Relations also exists on model-level. Querying of form WITH json_object included as part of results already works.
Current solution
I'v been using lots of static model methods for saving in order to separate saving logic from controller to model. Due to this I'v been passing an object representation of request-input to models save. For an example:
// FormController.php
Form:::saveForm($request->input('form'));
// FormModel.php
public function jsonObject() {
return $this->belongsTo('App\JsonObject');
}
public static function saveForm(Object $in) {
if(isset($in->id) && $in->id > 0) {
$out = Form::find($in->id);
$out->fill((array) $in);
} else {
$out = new Form();
$out->fill((array) $in);
}
// ... any custom saving logics are handled here as well
if(isset($in->json_object)) {
// handle processing of json_object;
}
$out->save();
return $out;
}
With this structure I'm able to pass related model as anonymous object. As "$in" is unrelated to form model class I'm able to access it's anonymous content as well.
Problem / Question
I'v been trying to figure out how this could be archieved by using an instantiated model. On controller level I would most likely do:
public function store(Request $request)
{
if($request->input("form.id") > 0) {
$form = Form::find($request->input("form.id"));
} else {
$form = new Form();
}
$form->fill($request->input("form"));
$form->saveForm();
return response()->json($form);
}
What would be the preferable way to implement processing (saving) of included related model as part of model-level logic? Note: I don't want to introduce JsonObjects saving logic as part of controller logic!
I could pass $json_object as an attribute of saveForm-method, but it sounds poor practice. On the other hand if I represent it as $attribute and $fillable feature of "Form" then saving fails due to attribute not really existing as an column on form-table.
The main goal here is to try to handle most of saving logic on model level. I don't want to represent any model-level logic on controller level, so that's why I want to represent the handling of related model on models method. "SaveForm()"-method would first handle saving of form and then call JsonObject::save() / JsonObject::saveObject(), which would handle processing of JsonObject on its own capsulation (in order to preserve code reusability).
One possible solution
I could add $json_object to formModel.php as ...
public $json_object;
... and manually fill this property on controller.
...
$form->fill($request->input("form"));
$form->json_object = $request->input("form.json_object");
...
// Then use it on formModel:
public function saveForm() {
...
if(isset($this->json_object)) {
// Handle saving logics
dd($this->json_object);
}
NOTE: fill-method doesn't fill json_object to form! $fillable seems to work only against $attributes array, and json_object is not column within forms-table.
Still, is there a better way for handling relations?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
