This works for deep relations by using nested foreach loops and fRequest::filter(). Here is a rough outline of what you would need to do.
Your inputs would all need to be named in the following form. $key
, $key_2
, etc should be replaced which integer keys. All fields and dependents that are part of the same group would use the same $key
and all field columns and dependents that are part of a field would use the same $key_2
, etc.
groups::group_id[$key]
groups::name[$key]
...
groups::fields::field_id[$key][$key_2]
groups::fields::group_id[$key][$key_2]
groups::fields::type[$key][$key_2]
...
groups::fields::dependents::dependent_id[$key][$key_2][$key_3]
groups::fields::dependents::field_id[$key][$key_2][$key_3]
groups::fields::dependents::column[$key][$key_2][$key_3]
fRequest::filter() is an internal function so you'll need to click the "Show Protected/Internal" link on the API docs page to see it. It takes a prefix and a key and replaces $_GET and $_POST with only the key/value pairs that start with $prefix and that match the $key specified. Once the request is filtered, you can then use a normal fActiveRecord::populate().
Here is some code that may help in your understanding. I know what I have presented isn't a complete working example, I just don't have time to write it all out.
$survey = new Survey();
$survey->populate();
$groups = array();
// This gets the keys to use with fRequest::filter()
$groups_keys = array_keys(fRequest::get('groups::group_id'));
foreach ($groups_keys as $group_key) {
fRequest::filter('groups::', $group_key);
$group = new Group();
$group->populate();
$fields = array();
$fields_keys = array_keys(fRequest::get('fields::field_id'));
foreach ($fields_keys as $field_key) {
fRequest::filter('fields::', $field_key);
$field = new Field();
$field->populate();
// continue nesting for dependents
$fields[] = $field;
fRequest::unfilter();
}
$group->associateFields($fields);
$groups[] = $group;
fRequest::unfilter();
}
$survey->associateGroups($groups);
$survey->store();
The store operation will validate all the way down the stack and should create friendly error messages for any level of relations. Similarly, all related records will be stored when you call the $survey->store()
.
Let me know if you need any clarification beyond this.