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
How to Reference a Lambda from Within Itself Using Ruby
Heroku: How to Push Seeds.Rb to Existing Rails App
Can't Convert Symbol into String
Why Is Date.Today - 6.Months + 6.Months != Date.Today
Using Nokogiri HTML Builder to Create Fragment with Multiple Root Nodes
Rspec and Shoulda - Complementary or Alternatives
Rails 3 Validates Inclusion of When Using a Find (How to Proc or Lambda)
Can't Run Jenkins Build - Bundle: "Command Not Found"
Cant Use Has_Secure_Password, Password_Digest Error
How to Bypass Mass Assignment Protection
Using Multiple Controllers in One View in Rails
Resetting a Singleton Instance in Ruby
Ruby: Write Escaped String to Yaml
How to Alias a Class Method in Rails Model