嵌套表单未在显示页面上显示提交的内容

时间:2016-04-13 22:12:49

标签: ruby-on-rails nested-forms

我正在尝试从Hartl的Rails教程中为应用添加一个轮询功能。通过关注#196 Nested Model FormNested forms with Rails 4.2 Strong Parameters开始。提交表单后,内容会正确保存到数据库中,但是,我无法在显示页面中看到结果,也无法找出原因。

模型 -

class Micropost < ActiveRecord::Base
  has_many :polls, dependent: :destroy
  accepts_nested_attributes_for :polls, :reject_if => lambda {|a| a[:content].blank? } 

  def questions_for_form
    collection = polls.where(micropost_id: id)
    collection.any? ? collection : polls.build
  end
end

class Poll < ActiveRecord::Base
  belongs_to :micropost
  has_many :answers, dependent: :destroy
  accepts_nested_attributes_for :answers, :reject_if => lambda {|a| a[:content].blank? }

  def answers_for_form
    collection = answers.where(micropost_id: id)
    collection.any? ? collection : answers.build
  end
end

class Answer < ActiveRecord::Base
  belongs_to :poll
end

控制器 -

class StaticPagesController < ApplicationController
  def home
    if logged_in?
      @micropost  = current_user.microposts.build
      @poll = @micropost.polls.build
        3.times {@poll.answers.build}
      @feed_items = current_user.feed.paginate(page: params[:page])
    end
  end
end

class MicropostsController < ApplicationController
  def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = "Micropost created!"
      redirect_to root_url
    else
      @feed_items = []
      render 'static_pages/home'
    end
  end

  private

    def micropost_params
      params.require(:micropost).permit(:content, polls_attributes: [:content, :id, :micropost_id, answers_attributes: [:content, :id, :poll_id]])
    end
end

class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
    @microposts = @user.microposts.paginate(page: params[:page])
  end
end

路线 -

Rails.application.routes.draw do
  resources :microposts,          only: [:create, :destroy]
  resources :polls
  resources :answers
end

视图 -

_micropost_form.html.erb

<%= form_for(@micropost) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.text_area :content, placeholder: "Compose new post..." %>
  </div>

  <button type="button" class="btn btn-default btn-xs" data-toggle="collapse" data-target="#pollcollapse" id="pollbtn">Poll</button>

  <div id="pollcollapse" class="collapse">
  <%= f.fields_for :polls do |questions_for_form| %>
    <%= render 'shared/poll_fields', :f => questions_for_form %>
  <% end %>
  </div>

  <%= f.submit "Post", class: "btn btn-primary" %>
<% end %>

_poll_fields.html.erb

<div class="field">
  <%= f.text_field :content, placeholder: "Poll question..."  %>
</div>

<%= f.fields_for :answers do |answers_for_form| %>
  <%= render 'shared/answer_fields', :f => answers_for_form %>
<% end %>

_answer_fields.html.erb

<div>
  <%= f.text_field :content, placeholder: "Answer" %>
</div>

show.html.erb

<% provide(:title, @user.name) %>
<div class="row">
  <aside class="col-md-4">
    <section class="user_info">
      <h1>
        <%= gravatar_for @user %>
        <%= @user.name %>
      </h1>
    </section>
  </aside>
  <div class="col-md-8">
    <% if @user.microposts.any? %>
      <h3>Posts (<%= @user.microposts.count %>)</h3>
      <ol class="microposts">
        <%= render @microposts %>
      </ol>
      <%= will_paginate @microposts %>
    <% end %>
  </div>
</div>

_micropost.html.erb

<li id="micropost-<%= micropost.id %>">

  <span class="content"><%= micropost.content %></span>

  <span>
    <% for poll in @micropost.polls %>    //Poll & answer content do not appear.
        <%= poll.content %>
        <% for answer in poll.answers %>
          <%= answer.content %>
        <% end %>
    <% end %>
  </span>

</li>

我认为这应该是所有相关信息,但如果我遗漏任何内容,请告诉我。非常感谢您提供任何帮助!

2 个答案:

答案 0 :(得分:0)

_micropost.html.erb部分内容中,您引用的@micropost似乎无法在任何地方定义。尝试将其从实例变量更改为本地变量micropost(了解@micropostmicropost here之间的差异。此外,在Ruby中,我们比我更聪明的人推荐(至少我read it多次)你应该使用.each而不是for。部分更新的代码:

<li id="micropost-<%= micropost.id %>">

  <span class="content"><%= micropost.content %></span>

  <span>
    <% micropost.polls.each do |poll| %>
        <%= poll.content %>
        <% poll.answers.each do |answer| %>
          <%= answer.content %>
        <% end %>
    <% end %>
  </span>

</li>

此外,由于您在show动作中定义@microposts,您可以在show视图中重构代码,如下所示:

<div class="col-md-8">
    <% if @microposts.any? %>
      <h3>Posts (<%= @microposts.count %>)</h3>
      <ol class="microposts">
        <%= render @microposts %>
      </ol>
      <%= will_paginate @microposts %>
    <% end %>
  </div>

答案 1 :(得分:0)

是实例与局部变量问题。我说它可能更容易使用gen,但是如果你正在学习rails并且你有时间,我的意见是第一次自己做它更好。当你遇到没有宝石的东西时,它可以帮助你学习框架并更好地解决问题。在了解了自己之后,如果你发现它真的符合你的目的,请选择宝石......或者制作自己的宝石!欢呼声。