Множество текстови полета в едно fields_for

Създавам приложение за управление на проекти и създавам проект с form_for, но вътре в него искам fields for за създаване на 3 ученика.

Настроих моя new.html.erb за проекти като този:

<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 %>

И за метода create току-що добавих един прост ред, за да видя моя form_for резултат:

  def create
    render text: params[:project].inspect
  end

Така че, когато попълня текстовите полета на страницата и натисна изпращане, всичко, което получавам, е {"name"=>"asd", "lecturer"=>"ffff", "students"=>{"name"=>"qeew"}}, така че, както можете да видите, само последният ми ученик беше прехвърлен към този речник.

Как мога да създам множество ученици в едно fields_for? Или как мога да настроя тези два модела да работят един с друг. Надявам се, че разбирате моята гледна точка и знаете какво искам да постигна.


person cojoj    schedule 11.12.2013    source източник


Отговори (2)


Бихте могли да създадете броя на учениците, за които трябва да имате полета във вашия контролер new действие, както следва:

# app/controllers/projects_controller.rb

def new
  @project = Project.new
  3.times do 
    student = @project.students.build
  end
end

Това ще изгради трима ученика в проектна инстанция.

След това актуализирайте form_for декларацията на вашия изглед, както следва:

# 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 %>
person vee    schedule 11.12.2013
comment
Без проблеми. Редактирах го през мобилния си телефон, така че подчертаването на синтаксиса не беше зададено правилно. Виждам, че пак си го редактирал :-) - person Rohit; 12.12.2013

Вероятно най-лесното нещо, което можете да направите, е да подадете правилен Project обект, вместо да го инициализирате от символ. След това добавете трима ученика към обекта и направете полета за цялата колекция.

За да направите това, бихте искали код като този в projects#new -

@project = Project.new
3.times { @project << Student.new }

След това във формата:

form_for @project do |f|
  ...
  f.fields_for :students do |s|
    s.label :name
    s.text_field :name
  end
end

fields_for автоматично ще генерира отделни полета за всеки ученик, който сте добавили към проекта в контролера.


В един момент не съм напълно сигурен: мисля, че това ще изисква да добавите линия accepts_nested_attibutes_for :students във вашия Project модел, но не съм съвсем сигурен. Това наистина има допълнителното предимство, че можете да създавате учениците и проекта доста лесно в действието за създаване в контролера, но не е правилният избор във всяка ситуация. Ако изглежда, че моето решение изисква accepted_nested_attributes_for и вие не го искате, уведомете ме и мога да актуализирам отговора си с подобно, макар и по-болезнено решение.

person Bubbles    schedule 11.12.2013