Обследование зданий от Railscast в рельсах 5

Я следил как за старыми, так и за пересмотренными рейлкастами, и это за то, что я должен сделать в том же духе

Я проследил это до определенного момента, но ни вопросы не отображаются в форме, ни ответы не добавляются. Ниже приведен мой код модели

answers.rb

class Answer < ActiveRecord::Base
  attr_accessor :content, :question_id
  belongs_to :question
end

surveys.rb

class Survey < ApplicationRecord
   attr_accessor :name, :questions_attributes
   has_many :questions
   accepts_nested_attributes_for :questions, allow_destroy: true
end

questions.rb

class Question < ApplicationRecord
  attr_accessor :content, :survey_id, :answers_attributes
  belongs_to :survey
  has_many :answers
  accepts_nested_attributes_for :answers, allow_destroy: true
end

Контроллер опросов

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

  # 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
    3.times do
      question = @survey.questions.build
      4.times { question.answers.build }
    end
  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, :question_id)
    end
end

Просмотры

_form.html.erb

<%= f.fields_for :questions do |builder| %>
  <%= render 'question_fields', f: builder %>
<% end %>
<%= link_to_add_fields "Add Question", f, :questions %>

_question_fields.html.erb

<fieldset>
  <%= f.label :content, "Question" %><br />
  <%= f.text_area :content %><br />
  <%= f.check_box :_destroy %>
  <%= f.label :_destroy, "Remove Question" %>
  <%= f.fields_for :answers do |builder| %>
    <%= render 'answer_fields', f: builder %>
  <% end %>
  <%= link_to_add_fields "Add Answer", f, :answers %>
</fieldset>

_answers_fields.html.erb

<p>
  <%= f.label :content, "Answer" %>
  <%= f.text_field :content %>
  <%= f.check_box :_destroy %>
  <%= f.label :_destroy, "Remove" %>
</p>

show.html.erb

<p id="notice"><%= notice %></p>

<p>
  <strong>Name:</strong>
  <%= @survey.name %>
</p>

<ol>
  <% for question in @survey.questions %>
  <li><%= h question.content %></li>
  <% end %>
</ol>

<p>
  <%= link_to "Edit", edit_survey_path(@survey) %> |
  <%= link_to "Destroy", @survey, :confirm => 'Are you sure?', :method => :delete %> |
  <%= link_to "View All", surveys_path %>
</p>

Миграции

class CreateSurveys < ActiveRecord::Migration[5.0]
  def change
    create_table :surveys do |t|
      t.string :name

      t.timestamps
    end
  end
end

class CreateQuestions < ActiveRecord::Migration[5.0]
  def change
    create_table :questions do |t|
      t.string :survey_id
      t.string :integer
      t.text :content

      t.timestamps
    end
  end
end

Есть ли что-то еще, что я пропускаю, что нужно сделать в rails 5, я часами занимался этим, и меня все еще смущает, почему он показывает мне эту ошибку - Таблица 'app.answers' не существует, когда я звоню ответы из вложенной формы. Любая помощь в этом отношении будет принята с благодарностью.

1 ответ

Решение

Основная проблема здесь заключается в том, что вы, похоже, забыли миграцию 'answer', чтобы создать таблицы, создать их и запустить, и все должно исправить.

Кроме того, те attr_accessor звонки будут портить вещи. Они требовались в более старых версиях Rails, но больше не нужны и теперь просто отбрасывают вещи. пример

С attr_accessor код

post = Post.new(title: "Something")
#=> #<Post id: nil, title: nil, created_at: nil, updated_at: nil>
post.title = "Something"
#=> "Something"
puts post
#=> #<Post id: nil, title: nil, created_at: nil, updated_at: nil>

Без

post = Post.new(title: "Something")
#=> #<Post id: nil, title: "Something", created_at: nil, updated_at: nil>
post.title = "Something Else"
#=> "Something Else"
puts post
#=> #<Post id: nil, title: "Something Else", created_at: nil, updated_at: nil>

Как вы можете видеть, первый блок, где моя модель Post имела attr_accessor для title атрибут, ничего не работает, как ожидалось; Я не мог обновить название. Как только я его убрал, все стало работать как надо.

Основываясь на обсуждении в чате, ваш _form.html.erb пропал, отсутствует form_for тег, и должен выглядеть примерно так

<%= form_for @survey do |f| %>
  <%= f.label :name %><br /> 
  <%= f.text_field :name %> 
  <!-- your current code here -->
<% end %>

у тебя есть _answers_field.html.erb И в _question_fields.html.erb звонят

<%= render 'answer_fields', f: builder %>

Обратите внимание, множественное / единственное несоответствие.

и, наконец, в вашем контроллере вы не разрешаете вложенные атрибуты params, которые должны выглядеть примерно так (если я не ошибаюсь)

def survey_params
  params.require(:survey).permit(:name, :question_attributes: [:id, :content, :_destroy, answer_attributes: [:id, :content, :_destroy])
end

Последние пару вопросов из чата были о том, что ассоциации нужны inverse_of так как belongs_to по умолчанию требуется в rails 5. И последнее, что не важно, это то, что Answer в настоящее время наследует ActiveRecord::Base и другие модели ApplicationRecord.

Другие вопросы по тегам