Вложенная форма в Rails 4 не отображается в поле зрения

Извините, если на этот вопрос уже был дан ответ, но я не могу найти ничего, что могло бы мне помочь. Я новичок в Rails, поэтому будьте осторожны: D

Я рвал на себе волосы, пытаясь заставить работать вложенные формы, я уверен, что в прошлом году я получил вложенные формы, работающие с помощью Rails 3 и демонстрации railscasts, но Rails 4 побеждает меня.

Глядя на журнал, выполняется запрос для извлечения данных для связанной таблицы, но в форме ничего не отображается.

Я прочитал много веб-сайтов, но пока ни один не помог, и я не знаю, с чего начать. Последняя статья, за которой я следил, это http://www.createdbypete.com/articles/working-with-nested-forms-and-a-many-to-many-association-in-rails-4./

По-прежнему ничего не отображается в представлении.

Где мне начать отлаживать это, может быть, моя установка Rails не работает?? Но я, вероятно, упускаю что-то важное.

Спасибо, Ройс

Изменить - я добавил некоторые контроллеры и рассматриваемое представление.

Surveys_controller.rb

class SurveysController < ApplicationController
  before_action :set_survey, only: [:show, :edit, :update, :destroy, :answers]

  # GET /surveys
  # GET /surveys.json
  def index
    @surveys = Survey.all
  end

  # GET /surveys/1
  # GET /surveys/1.json
  def show
  end

  # GET /surveys/new
  def new
    @survey = Survey.new
  end

  # GET /surveys/1/edit
  def edit
  end

  # POST /surveys
  # POST /surveys.json
  def create
    @survey = Survey.new(survey_params)

    respond_to do |format|
      if @survey.save
        format.html { redirect_to @survey, notice: 'Survey was successfully created.' }
        format.json { render :show, status: :created, location: @survey }
      else
        format.html { render :new }
        format.json { render json: @survey.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /surveys/1
  # PATCH/PUT /surveys/1.json
  def update
    respond_to do |format|
      if @survey.update(survey_params)
        format.html { redirect_to @survey, notice: 'Survey was successfully updated.' }
        format.json { render :show, status: :ok, location: @survey }
      else
        format.html { render :edit }
        format.json { render json: @survey.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /surveys/1
  # DELETE /surveys/1.json
  def destroy
    @survey.destroy
    respond_to do |format|
      format.html { redirect_to surveys_url, notice: 'Survey was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  def answers
    @participants = Participant.all
    @questions = @survey.questions
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_survey
      @survey = Survey.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def survey_params
      params.require(:survey).permit(:name,
      :questions_attributes => [:id, :content,
        :answers_attributes => [:id, :content, :participant_id]
      ])
    end
end

участников_controller.rb

class ParticipantsController < ApplicationController
  before_action :set_participant, only: [:show, :edit, :update, :destroy]

  # GET /participants
  # GET /participants.json
  def index
    @participants = Participant.all
  end

  # GET /participants/1
  # GET /participants/1.json
  def show
  end

  # GET /participants/new
  def new
    @participant = Participant.new
  end

  # GET /participants/1/edit
  def edit
  end

  # POST /participants
  # POST /participants.json
  def create
    @participant = Participant.new(participant_params)

    respond_to do |format|
      if @participant.save
        format.html { redirect_to @participant, notice: 'Participant was successfully created.' }
        format.json { render :show, status: :created, location: @participant }
      else
        format.html { render :new }
        format.json { render json: @participant.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /participants/1
  # PATCH/PUT /participants/1.json
  def update
    respond_to do |format|
      if @participant.update(participant_params)
        format.html { redirect_to @participant, notice: 'Participant was successfully updated.' }
        format.json { render :show, status: :ok, location: @participant }
      else
        format.html { render :edit }
        format.json { render json: @participant.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /participants/1
  # DELETE /participants/1.json
  def destroy
    @participant.destroy
    respond_to do |format|
      format.html { redirect_to participants_url, notice: 'Participant was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_participant
      @participant = Participant.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def participant_params
      params.require(:participant).permit(:name)
    end
end

application_controller.rb

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
end

ответы.html.erb

<h1><%= @survey.name %> Answers</h1>

<%= form_for(@survey) do |f| %>
  <% @participants.each do |participant| -%>
  <h3><%= participant.name %></h3>
  <table>
    <thead>
      <tr>
        <td>Questions</td>
        <td>Answer</td>
      </tr>
    </thead>
    <tbody>
      <% @questions.each do |question| -%>
      <tr>
        <td><%= question.content %></td>
        <td>
        <%= f.fields_for :questions, question do |q| -%>
          <%= q.fields_for :answers, question.answers.find_or_initialize_by(participant: participant) do |a| -%>
            <%= a.text_area :content %>
            <%= a.hidden_field :participant_id, participant.id %>
          <% end -%>
        <% end -%>
        </td>
      </tr>
      <% end -%>
    </tbody>
  </table>
  <% end -%>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end -%>

person Royceybaby    schedule 14.08.2014    source источник
comment
Быстрое предложение: опубликуйте небольшой код здесь. Возможно метод контроллера и само представление.   -  person mylescarrick    schedule 14.08.2014
comment
Ура, Майлз, надеюсь, что это поможет.   -  person Royceybaby    schedule 14.08.2014
comment
Пожалуйста, опубликуйте содержание модели опроса. Вы, вероятно, пропустили accept_nested_attributes_for :questions   -  person coorasse    schedule 14.08.2014
comment
Вложенные формы уродливы, запутаны и ломки — и вам нужно помнить, что нужно правильно делать множество мелочей по всему стеку. Вы можете сделать вещи намного проще для понимания и помочь изолировать изменения, используя объекты формы. Объекты формы притворяются моделями, поэтому при работе с контроллером или представлением они работают так же, как и модели. Об этом есть про Railscast или см.: stackoverflow.com/questions/25296385/   -  person A Fader Darkly    schedule 14.08.2014
comment
Выглядит интересно, надо будет почитать   -  person Royceybaby    schedule 14.08.2014


Ответы (3)


Поскольку вы новичок в Rails, позвольте мне объяснить вам, как работают вложенные формы!

--

Вложенные

Вложенные формы на самом деле вообще не являются вложенными — это ассоциативные формы.

Вы должны помнить, что Rails (в силу того, что он построен на Ruby) является объектно-ориентированным< /em> фреймворк. ООП (объектно-ориентированное программирование) — это не просто модное словечко — это фундаментальная основная конструкция вашего приложения и то, как оно обрабатывает ввод/выполнение.

Проблема многих людей заключается в том, что они не осознают истинной природы Rails и, следовательно, не понимают, как работают его многочисленные функции. Если вы понимаете, что все, что вы делаете в Rails, должно быть построено вокруг объектов, жизнь становится намного проще!

введите здесь описание изображения

--

Форма

Имея это в виду, вы можете начать ценить роль objects во всем Rails до такой степени, что вам нужно создавать/вызывать объекты для каждого элемента вашего приложения Rails, включая вашу форму:

#app/models/survey.rb
Class Survey < ActiveRecord::Base
   has_many :questions
   accepts_nested_attributes_for :questions
end

#app/controllers/surveys_controller.rb
Class SurveysController < ApplicationController
   def new
       @survey = Survey.new
       @survey.questions.build #-> very important
   end
end

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

Это должно создать форму, которая позволит вам передавать ассоциативные данные в вашу дочернюю модель. Есть несколько важных элементов, которые следует учитывать:

  1. Вам необходимо включить accepts_nested_attributes_for в вашу "родительскую" модель.
  2. Вам нужно build ассоциативные объекты
  3. Вам нужно заполнить форму относительными объектами

Следуя этому простому шаблону, вы сможете заполнить вложенную форму, которую хотите отобразить в представлении.

person Richard Peck    schedule 14.08.2014
comment
Спасибо, Рич, я пропустил @survey.questions.build. Просто нужно понять, почему мой основной проект не работает сейчас! Та же проблема. - person Royceybaby; 14.08.2014
comment
Нет проблем - в чем проблема с вашим основным проектом? Может быть, мы могли бы это исправить? - person Richard Peck; 14.08.2014
comment
Та же проблема Rich, форма не отображает вложенные атрибуты. Приведенный выше код был попыткой выяснить, почему он не работает. Сделал то же самое в основном проекте, но не рендерит. - person Royceybaby; 14.08.2014

Попробуйте использовать следующий код:

<%= f.fields_for :questions do |q| -%>
      <%= q.fields_for :answers, q.object.answers.find_or_initialize_by(participant: f.object.participant) do |a| -%>
        <%= a.text_area :content %>
        <%= a.hidden_field :participant_id, participant.id %>
      <% end -%>
    <% end -%>

и убедитесь, что вы визуализируете в answers.html.erb, у вас есть accepts_nested_attributes_for :questions в файле survey.rb и accepts_nested_attributes_for :answers в файле question.rb

person Mohamed Yakout    schedule 14.08.2014

Есть ли в вашей модели опроса accepts_nested_attributes_for :question? И то же самое для модели ответа?

person Ralph King    schedule 14.08.2014