I'm building a form where a user should be able to create a template with fields. However they should also be able to create an optional Collection
which belongs_to
each Field
at the same time.
So far it looks like this:
Tables
templates: id, name template_fields: id, template_id, collection_id, field_name collections: id, name collection_values: id, collection_id, value
Models
Template
class Template < ActiveRecord::Base has_many :template_fields accepts_nested_attributes_for :template_fields end
Template Fields
class TemplateField < ActiveRecord::Base belongs_to :template belongs_to :collection end
Collection
class Collection < ActiveRecord::Base has_many :collection_values end
CollectionValue
class CollectionValue < ActiveRecord::Base belongs_to :collection end
How can I create these objects? How do I go about this in the controller?
The only way I can think of is to create it as a nested association (even though Collection isn't really a nested attribute) or create the Collections before the Templates, and somehow link each Field to each Collection that was created.
Controller
def create @template = Template.new(template_params) if @template.save flash[:notice] = "Template successfully created." flash[:color]= "valid" redirect_to templates_path else flash[:notice] = "Form is invalid" flash[:color]= "invalid" render :new end end def template_params params.require(:template).permit(:id,:name, template_fields_attributes: [:id, :template_id, :field_name, :collection_id, collection_values_attributes: [:value] ]) end
3 Answers
Answers 1
I think you need to add these kind of relationships to your model has_many :through
and has_one :through
to relate collection
and collection_values
to template
and then modify your template.rb to include:
has_one :collection, through: :template_fields
The line above assumes that one template has only one collection
has_many :collection_values, through: :collection accepts_nested_attributes_for :template_fields, :collection, :collection_values
You also need to modify the template_params
in your controller to include collection_attributes
and collection_values_attributes
Answers 2
For requirements given you may have:
class CollectionValue < ActiveRecord::Base belongs_to :collection end class Collection < ActiveRecord::Base has_many :collection_values accepts_nested_attributes_for :collection_values end class TemplateField < ActiveRecord::Base belongs_to :template belongs_to :collection accepts_nested_attributes_for :collection end class Template < ActiveRecord::Base has_many :template_fields accepts_nested_attributes_for :template_fields end
That would make following code work:
Template.create name: 'template_name', template_fields_attributes: [ {name: 'field_name', collection_attributes: {name: 'collection_name', collection_values_attributes: [ {name: 'col_value_1'}, {name: 'col_value_2'} ]} } ]
You may try it in rails console. This example would create all of records as it doesn't include any IDs. It would work same way in TemplateController#create
It's better for you to read and understand accepts_nested_attributes_for
Answers 3
This can be done - however it required manipulating the params
to a large extent and was very convoluted/tightly coupled. Have opted to use AJAX to create a collection
before the form is saved.
0 comments:
Post a Comment