This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.
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
Hello,
How can you pass some data/variable to the subform?
Im trying to pass the form id so as to dynamically set the values of a dropdown in the subform.
This is a great tutorial Tschallacka - something that's very relevant to a lot of people I'm sure.
One thing I'm confused about is where it's forcing the hotel entry in the example. It is not forcing anything in the situation where I am using a relationship form and I'm not sure if it's because I'm missing something that is not explicitly stated in the tutorial.
Last updated
Tschallacka, thanks for the tutorial. When I try to create a model with a hasMany relation, the hasMany relation is created in the database but it does not display in the list view until after I save the parent model. Have you had this problem?
All other relations (besides hasMany) appear in the view upon creating the parent model. It's just the hasMany relations that don't show.
In update of the parent model, all of the hasMany relations are listed as expected. This is quite a problem when you need to enter various data and you don't remember what was already entered.
I am using a separate database so I wonder if this may cause this problem.
Could you or someone please point me in the right direction for how to solve this?
@indigo try making a detailed issue report on the Github repository for this and we'll take a look. More detail you can provide the better equipped we are to help you out.
But what if I have a one-to-one relationship and just want to add a set of fields (subform for the related item) inside the form instead of having a list with add/update buttons on the top?
Bro.
I don't know who you are. I don't know what you do. But what I do have are a very particular set of skills; skills I have acquired over a very long career. I will look for you, I will find you, and I will buy you anything you want.
Thanks
1-11 of 11