rails在 rails 5 中施放的建筑调查

Building survey from railscast in rails 5

我一直在关注旧版和修订版 railscasts & this,因为我必须按照相同的思路做一些事情

我一直关注到某个点,但表格上既没有显示问题,也没有添加答案。以下是我的模型代码

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 中完成吗,我已经花了好几个小时了,但它仍然让我感到困惑,为什么它会向我显示这个 错误 - Table 'app.answers' 不存在 当我从嵌套表单调用答案时。非常感谢这方面的任何帮助。

这里的主要问题是您似乎忘记了 '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 模型具有 title 属性的 attr_accessor,但没有按预期工作;我无法更新标题。一旦我删除它,一切就开始正常工作了。

根据聊天讨论,您的 _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 %>

注意,plural/singular 不匹配。

最后,在您的控制器中,您不允许嵌套的属性参数最终看起来像(除非我弄错了)

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