-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Nested Models
Nested Models let you build forms that update an object and it's associated objects all in one shot.
(note this is a work in progress!)
To use nested models with simple_form, there are two rails features that you have to understand:
-
accepts_nested_attributes_for- anActiveRecordclass method that goes in your model code - it lets you create and update child objects through the associated parent. An in depth explanation is available in theActiveRecorddocumentation. -
fields_for- a helper method that goes in your view code - it builds form fields for your nested models
TBD - format this text and add some reference links
Let's take a simple example:
class Machine < ActiveRecord::Base
has_many :parts
accepts_nested_attributes_for :parts
end
class Part < ActiveRecord::Base
# name:string
belongs_to :machine
endWith these models, we can use simple_form to update the machine and its associated parts in a single form:
<%= simple_form_for @machine do |m| %>
<%= m.simple_fields_for :parts do |p| %>
<%= p.input :name %>
<% end %>
<% end %>For 'new' action, build the nested model from the controller:
def new
@machine = Machine.new
@machine.parts.build
ende.g. if Machine has_one Color, accepts_nested_attributes_for must be called with :color.
accepts_nested_attributes_for :colorAnd in your Controller#new action, you should make a new instance for the :color attribute:
def new
@machine = Machine.new
@machine.build_color
endIf you have non-ActiveRecord models, then refer to Use with ActiveModel compliant models page.
To fill the label of the value field with the key attribute and give it an ID so we can grab it with Capybara, we can access the object in question by calling nested_form.object
<%= simple_form_for @user do |m| %>
<%= m.simple_fields_for :custom_fields do |c| %>
<%= c.input :field_key, as: :hidden %>
<%= c.input :field_value, label: c.object.field_key, input_html: { id: c.object.field_key } %>
<% end %>
<% end %>If you need to get this working with Strong Parameters (http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html)
<%= simple_form_for @machine do |m| %>
<% @machine.parts.each do |part| %>
<%= field_set_tag 'Part' do %>
<%= f.simple_fields_for "parts_attributes[]", p do |pf| %>
<%= pf.input :name %>
<% end %>
<% end %>
<% end %>
<% end %>and in the controller
def machine_params
params.require(:machine).permit(:parts_attributes => [:name])
endThis page was created by the OSS community and might be outdated or incomplete. Feel free to improve or update this content according to the latest versions of SimpleForm and Rails to help the next developer who visits this wiki after you.
Keep in mind to maintain the guides as simple as possible and to avoid additional dependencies that might be specific to your application or workflow (such as Haml, RSpec, Guard and similars).