I’m building a web application that needs a somewhat complex form to function.
I have five models: Grid, Row, Value, VariableGroup and Variable (these are not the actual names but useful for reference).
A Grid has many rows, and a Row has many values. Also, a Grid belongs to a VariableGroup, which is a sort of a model that groups many variables for their grandchildren.
A Variable, of course, belongs to a VariableGroup, and the key here, is that a Value belongs to a Variable as well.
The models:
class Grid < ActiveRecord::Base
belongs_to :variable_group
has_many :rows
accepts_nested_attributes_for :rows, :allow_destroy => true
end
class Row < ActiveRecord::Base
belongs_to :grid
has_many :values
accepts_nested_attributes_for :values, :allow_destroy => true
end
class Value < ActiveRecord::Base
belongs_to :variable
belongs_to :row
end
class Variable < ActiveRecord::Base
belongs_to :variable_group
end
class VariableGroup < ActiveRecord::Base
has_many :variables
has_many :grids
end
The expected behavior is as follows to create a new Grid:
The user must select a VariableGroup from a dropdown select. This select has a jQuery handler for .change, that must instantiate a nested Row model, which in turn instantiates as many Value models as Variables exist in the Grid’s selected VariableGroup.
This is the grid form:
= simple_form_for @grid, :html => {:class => 'form-horizontal' } do |f|
= f.input :name
= f.association :variable_group_id
.rows_and_values_container
= f.simple_fields_for :rows do |p|
= render 'rows_fields', :f => p
= f.submit
And this is the attached listener:
$('document').ready(function(){
$('#grid_variable_group_id').change(function(){
$.ajax({url: '/grids/load_variables_in_values',
data: 'selected=' + this.value,
dataType: 'script'})
});
});
And this is the load_variables_in_values action:
def load_variables_in_values
@grid = Grid.new
row = @grid.rows.build
@variables = Variable.where(:variable_group_id => params["selected"])
@variables.each do |variable|
value = row.values.build
value.variable_id = variable.id
end
# render :partial => "test_data_sets_fields"
respond_to do |format|
format.js
end
end
The respond_to block yields the control to a js.erb view that should load the following partial, but I’m stuck here as I don’t know where and how to handle the loading of the partial and its sub-partials:
#rows_fields partial
= f.input :name
= f.input :grid_id #Should be hidden
= f.simple_fields_for :test_data_values do |p|
= render 'values_fields', :f => p
#values_fields partial
= f.input :value
= f.input :row_id #Should be hidden
= f.input :variable_id #Auto-assigned
I think I’m 80% there, but I don’t know how to load the partials with its corresponding values with the data that I process in the custom controller action that was called via AJAX.
I know this is a mile long post, so thanks in advance if you got ºhere.
Rendering a partial from the custom controller action instead of using a respond_to block worked.
I just had to hard-code the scope of the form (reading the source of the auto generated form and using its structure as a string, together with a random value, and it worked.