How to Handle Multiple Models in One Rails Form

How to handle multiple models in one rails form?

You can handle as many forms as you need, if you use the fields_for helper properly.

This is where you're falling short I think (your controller seems okay).

I also wrote an answer about this some time back.

#app/models/survey.rb
class Survey < ActiveRecord::Base
has_many :sections
accepts_nested_attributes_for :sections
end

#app/models/section.rb
class Section < ActiveRecord::Base
belongs_to :survey
has_many :questions
accepts_nested_attributes_for :questions
end

#app/models/question.rb
class Question < ActiveRecord::Base
belongs_to :section
has_many :answers
end

Try and keep your model names as succinct as possible.

#app/controllers/surveys_controller.rb
class SurveysController < ApplicationController
def new
@survey = Survey.new
@survey.sections.build.questions.build
end

def create
@survey = Survey.new survey_params
@survey.save
end

private

def survey_params
params.require(:survey).permit(:title, sections_attributes: [:title, questions_attributes:[:title]])
end
end

#app/views/surveys/new.html.erb
<%= form_for @survey do |f| %>
<%= f.text_field :title %>
<%= f.fields_for :sections do |section| %>
<%= section.text_field :title %>
<%= section.fields_for :questions do |question| %>
<%= question.text_field :title %>
<% end %>
<% end %>
<%= f.submit %>
<% end %>

how to handle multiple models in a rails form

Two options:

First is ActivePresenter which works well for this.

Second is just to use fields_for:

<%= form_for @user do |f| %>

<%=f.label :name %>
<%=f.text_field :name %>

<%= fields_for @address do |fa| %>
<%=fa.label :city %>
<%=fa.text_field :city %>
<% end %>

<% end %>

Then in the controller, save the records.

 @user = User.new(params[:user]) 
@address = Address.new(params[:address])

ActivePresenter works so well though.

Also found a railsforum post via Google, which would work well.

Using form_for with multiple models?

I think you are looking for rails built-in helper fields_for.

See the docs here.

Rails - one form to two models

You'll be best looking into accepts_nested_attributes_for:

#app/models/store.rb
class Store < ActiveRecord::Base
has_one :address
accepts_nested_attributes_for :address
end

#app/controllers/stores_controller.rb
class StoresController < ApplicationController
def new
@store = current_user.stores.new
@store.build_address
end

def create
@store = current_user.stores.new store_params
@store.save
end

private

def store_params
params.require(:store).permit(:store_type_id, :latitude, :longitude, :name, :notes, address_attributes: [:line_1])
end
end

#app/views/stores/new.html.erb
<%= form_for @store do |f| %>
<%= f.fields_for :address do |a| %>
<%= a.text_field :line_1 %>
<% end %>
<%= f.submit %>
<% end %>

saving to multiple models from one form with rails

I think you have a syntax error in the form. The fields_for is a method of f and it expects a plural symbol. It is also a good practice to have the iterator of a block in singular, and not to use parentheses when your method only expects one parameter:

<%= form_for(@venue, :url =>{:action => 'create'}) do |f| %>

Artist ID<br />
<%= f.fields_for :events do |event_field| %>
<%= event_field.text_field :artist_id %><br/><br />
<% end %>

Venue City<br />
<%= f.text_field :city %> <br /><br />
Venue Name<br />
<%= f.text_field :name %><br/><br/>

<div class="actions">
<%= submit_tag "Save", :class => "btn primary" %>
</div>

<% end %>

See this example of a nested form in Ryan Bate's Railscasts:

<%= form_for @survey do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<% f.fields_for :questions do |builder| %>
<p>
<%= builder.label :content, "Question" %><br />
<%= builder.text_area :content, :rows => 3 %>
</p>
<% end %>
<p><%= f.submit "Submit" %></p>
<% end %>

Ruby on Rails: create records for multiple models with one form and one submit

To submit a form and it's associated children you need to use accepts_nested_attributes_for

To do this, you need to declare it at the model for the controller you are going to use (in your case, it looks like the Quote Controller.

class Quote < ActiveRecord::Base
attr_accessible :quote_number
has_one :customer
has_one :item
accepts_nested_attributes_for :customers, :items
end

Also, you need to make sure you declare which attributes are accessible so you avoid other mass assignment errors.

Submit form with multiple models

A not so elegant solution is to do the following

    <p>
<%= text_field_tag 's_url[0]' %><br />
<%= text_field_tag 'i_url[0]' %>
</p>

<p>
<%= text_field_tag 's_url[1]' %><br />
<%= text_field_tag 'i_url[1]' %>
</p>

Back in your controller, params[:s_url] and params[:i_url] will contain arrays of all the values.

Using jQuery you could easily generate the form with as many records as you want, and even add more on the fly.

However, this is not a clean solution.

A bit slower but way cleaner, is to pass a collection of your model to the form. This will create some extra server side calls when you want to increase the list, but I still find it to be a much better solution.

Example from fields_for documentation

<%= form_for @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
Project #<%= project_fields.index %>
...
<% end %>
...
<% end %>

Of course, best would be to use a client-side MVC framework like Angular or Ember, but I'm not sure how feasible is this for you.



Related Topics



Leave a reply



Submit