Reputation: 6475
I'm building Project Management application and I'm creating Project with form_for
but inside it I want a fields for
to create 3 students.
I've set up my new.html.erb
for Projects like this:
<h1>Creating new project</h1>
<%= form_for :project, url: projects_path do |f| %>
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :lecturer %>
<%= f.text_field :lecturer %>
</p>
<p>
<%= f.fields_for :students do |s| %>
<%= s.label :name %>
<%= s.text_field :name %><br>
<%= s.label :name %>
<%= s.text_field :name %><br>
<%= s.label :name %>
<%= s.text_field :name %>
<% end %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
And for the create
method jusst added one simple line to see my form_for
result:
def create
render text: params[:project].inspect
end
So when I fill up the text fields on page and hit submit all I get is {"name"=>"asd", "lecturer"=>"ffff", "students"=>{"name"=>"qeew"}}
so as you can see only my last student was passed to this dictionary.
How can I create multiple students in one fields_for
? Or how can I set up these two models to work with each other. I hope you get my point of view and know what I want to achieve.
Upvotes: 2
Views: 2151
Reputation: 38645
You could build the number of students you need to have fields for in your controller new
action like follows:
# app/controllers/projects_controller.rb
def new
@project = Project.new
3.times do
student = @project.students.build
end
end
This will build three students under project instance.
Then update your view's form_for
declaration as follows:
# app/views/projects/new.html.erb
<%= form_for @project, url: projects_path do |f| %>
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :lecturer %>
<%= f.text_field :lecturer %>
</p>
<p>
<%= f.fields_for :students do |s| %>
<%= s.label :name %>
<%= s.text_field :name %>
<% end %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
Upvotes: 3
Reputation: 3815
Probably the easiest thing to do would be to pass in a proper Project
object, instead of initializing it off of a symbol. Then, add three students to the object, and do a fields for the entire collection.
To do this, you'd want some code like this in projects#new
-
@project = Project.new
3.times { @project << Student.new }
Then over in the form:
form_for @project do |f|
...
f.fields_for :students do |s|
s.label :name
s.text_field :name
end
end
The fields_for
will automatically generate separate fields for each student that you added to the project in the controller.
One point I'm not entirely sure about: I think this will require you add a line accepts_nested_attibutes_for :students
in your Project
model, but I'm not quite sure. This does have the added advantage that you can create the students and the project quite easily in the create action in the controller, but isn't the right choice in every situation. If my solution does appear to require accepted_nested_attributes_for
and you don't want it, let me know and I can update my answer with a similar, if more painful, solution.
Upvotes: 1