铁路轨道建筑的建筑调查5

时间:2017-07-08 07:30:43

标签: ruby-on-rails ruby model-view-controller ruby-on-rails-5 nested-forms

我一直关注旧的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中完成的事情,我已经花了好几个小时了,它仍然让我感到困惑,为什么它会告诉我这个错误 - 表&#39; app.answers& #39;当我从嵌套表单中调用答案时,它不存在。在这方面的任何帮助将非常感谢。

1 个答案:

答案 0 :(得分:1)

这里的主要问题是,您似乎忘记了“回答”迁移来创建表,创建并运行它并应该解决问题。

此外,那些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 %>

注意,复数/单数不匹配。

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

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

聊天中的最后几个问题是关联需要inverse_of,因为在rails 5中默认需要belongs_to。最后一个小问题是Answer当前正在继承ActiveRecord :: Base和其他型号ApplicationRecord