This took me a while to piece together how it works and all, so here's the guide how to easily put a management form for your relationships within your current form.
For this example i'm going to assume the following:
- You know how to make a backend form
- You know how to make a controller
- You know how to make a model
- You know how to make the database/schema structure
In this example we are trying to set up a hotel, and a hotel has a lot of facilities.
The facilities have the relationship: belongsTo hotel
public $belongsTo = [
'hotel' => [
'ExitControl\HotelManager\Models\HotelManagerModel',
],
];
The hotels have the relationship: hasMany facilities
public $hasMany = ['facilities' => [
'Tschallacka\HotelManager\Models\HotelFacilityModel',
'key' => 'hotel_id'
],
];
They are linked togeter by hotel_id in the facilities(foreign key in my setup but that's not required for this to work)
Important to know
When you edit via the form we are going to make it will default save the hotel_id in the facilities table. So there is no need to have a hotel selection form in that form. Even if you include it, any selections you make in there will be blatantly ignored.
Setting fillables
You need to define which fields are fillable in your model. If you do not define these you'll get an error saying something along the line of Mass assignment failed for field 'something youforgot'.
If you get this error when trying to save, copy and paste that field name into the fillables.
You need to set the fillable array in the model the "subform" belongs to. In this case HotelFacilityModel needs to have the fields it can save/update fillable.
It's important that you use the "model" field names here. So if you defined a relationship, you need to use the relationship name instead of the database name.
protected $fillable = ['active','facility'];
In my facilities I have two fields I need to set, if it's active(yes/no) and which facility it is. The hotel entry is missing here because as I stated before, that will be filled automatically.
Making the controller behave
In the HotelController.php we need to add the behaviour RelationController to it. So in the top we add Backend.Behaviors.RelationController to the $implement array.
public $implement = [
'Backend.Behaviors.FormController',
'Backend.Behaviors.ListController',
'Backend.Behaviors.RelationController' // <----
];
And we define where we can find our relationship configuration file in the HotelController
public $relationConfig = 'config_relation.yaml';
Now to create this config_relation.yaml file you go to your \controllers\hotelcontroller directory where also your config_form.yaml resides and all the views for the forms and create there a new file called config_relation.yaml
In it post
facilities:
label: Facilities
manage:
form: $/tschallacka/hotelmanager/models/hotelfacilitymodel/relation_fields.yaml
list: $/tschallacka/hotelmanager/models/hotelfacilitymodel/relation_columns.yaml
view:
list: $/tschallacka/hotelmanager/models/hotelfacilitymodel/relation_columns.yaml
toolbarButtons: create|delete
For other types of relations read: http://octobercms.com/docs/backend/relations#relationship-types
As you might notice I have defined here relation_fields.yaml and relation_columns.yaml and you might be wondering what these fields are.
These are the exact same fields in your model for building up your form minus the hotel choosing element. So basically copy over fields.yaml and columns.yaml and remove the hotel field and rename them to what you defined here in the config_relation.yaml
Adding the form to your hotel management form
Now go to your PluginName\hotelmanager\hotelmanagermodel folder and open up fields.yaml
facilities:
label: facilities
span: left
type: partial
tab: tschallacka.hotelmanager::lang.hotelmanagermodel.hotelfacilities
path: ~/plugins/tschallacka/hotelmanager/controllers/hotelcontroller/_facilities.htm
You might notice we are using a partial here instead of just adding it to the form. This is because we need to call a special piece of php code to actually render the relationship editor we just defined.
Creating the "renderer"
Go back to your hotelcontroller directory where also your config_relation.yaml resides and create a new file _facilities.htm
In it put the following code:
<?= $this->relationRender('facilities'); ?>
Make sure you use here the relationship name you defined in the relation_config.yaml. In this case 'facilities'
And that's it. Now you have a subform in a form.
Important nice details
If you use a seperate database connection than than default OctoberCMS install database you need to copy over the OctoberCMS.deferred_bindings table to your other database for things to work properly.
Last updated