I have this structure in my view:
<%= simple_form_for @user ... %>
...
...
<%= render '/hobbies/form', :user => @user %>
...
...
<% end %>
The render part loads data from a partial - there's a form. The form-fields are successfully loaded (like inputs, submit input, radio buttons etc), but when I take a look at the generated HTML, in the rendered form is missing <%= form_for...
and the closing tag.
Which means when I click to the submit button from the rendered form, this rendered form is not sent out, but instead of it is sent out the "big" for - simple_form_for
.
How to make the rendered form sendable?
Thank you
Simply, you can't have two separate nested forms.
You can have nested associated forms using accepts_nested_attributes_for
- this is dependent on the structure of your models in the backend, which I'll detail below.
--
Forms
The most important thing you need to know is that Rails just builds HTML forms - which means they have to abide by all the constraints & rules these forms stipulate:
Each form has its own action
attribute - which is how your browser knows where to send the data. If you have multiple / nested forms, you'll basically have two of these "action" attributes; preventing HTML from sending the form correctly
--
Nested
If you want to use some Rails conventions, you'll be better using the accepts_nested_attributes_for
method. This resides in the model, and in order to use it effectively, you need to ensure you have your ActiveRecord associations
set up correctly:
#app/models/user.rb
Class User < ActiveRecord::Base
has_many :hobbies
accepts_nested_attributes_for :hobbies
end
#app/models/hobby.rb
Class Hobbies < ActiveRecord::Base
belongs_to :user
end
The importance of the association is crucial - Rails will pass "nested" model data through to each other. The nested model data is only there if the models are associated correctly with ActiveRecord (as above)
You can then pass the data through your controller / models as follows:
#app/controllers/users_controller.rb
Class UsersController < ApplicationController
def new
@user = User.new
@user.hobbies.build # -> essential for nested attributes
end
def create
@user = User.new(user_params)
@user.save #-> notice how this saves the @user model only?
end
private
def user_params
params.require(:user).permit(:user, :attributes, hobbies_attributes: [:hobbies, :attributes])
end
end
This will allow you to include the hobbies
part of the form as follows:
<%= form_for @user do |f| %>
<%= f.fields_for :hobbies do |h| %>
<%= h.text_field :your_attributes %>
<% end %>
<% end %>
Nested forms is not valid html. To achieve this you have to either un-nest your forms or use javascript. If you opt for the javascript approach, you simple catch the form submit event, prevent the default, and manually submit the form you want.
EDIT:
If you opt for the javascript approach, consider that you might not need two forms at all. Instead you can just add a click handler for the button on your 'sub action' which makes an ajax request.
Alternatively, if javascript is not an option, and rearranging the html is not an option, you could handle this on the server by submitting the data from both forms and processing each differently depending on which submit input was clicked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With