【问题标题】:Rails - nested form won't display in edit templateRails - 嵌套表单不会显示在编辑模板中
【发布时间】:2016-02-27 13:48:42
【问题描述】:

我创建了一个表单,它允许用户通过单击文本或 URL 按钮来动态添加嵌套表单字段。可以添加 Text 或 Url 字段的任何排列(也可以删除它们)。

示例 - http://imgur.com/4ldNEem

提交表单时,内容会显示在视图模板中。但是,当我在 /posts/id/edit 编辑帖子时,帖子内容不会出现在编辑模板中 - 这是一个空白页面。

SQL日志http://i.stack.imgur.com/B2ueq.png

后模型

class Post < ActiveRecord::Base
 has_many :things, dependent: :destroy
 accepts_nested_attributes_for :things
end 

事物模型

class Thing < ActiveRecord::Base
 belongs_to :post
end 

架构

create_table "posts", force: :cascade do |t|
 t.datetime "created_at", null: false
 t.datetime "updated_at", null: false
end

create_table "things", force: :cascade do |t|
 t.text     "text"
 t.string   "url"
 t.integer  "post_id"
end

帖子控制器

class PostsController < ApplicationController

def edit
 @post = Post.includes(:things).find(params[:id])
end 

def update
end 

new.html.erb

<button id='addtext'>text</button>
<button id='addurl'>url</button>

<%= form_for @post, url: posts_path, html: { multipart: true } do |f| %>

 <%= f.fields_for :thing do |ff| %>
 <% end %> 
 <%= f.submit %>
<% end %>

edit.html.erb

<button id='addtext'>text</button>
<button id='addurl'>url</button>

<%= form_for @post, url: posts_path, html: { multipart: true } do |f| %>

 <%= f.fields_for :thing do |ff| %>
 <% end %> 
 <%= f.submit %>
<% end %>

posts.coffee

删除字段

jQuery ->
 $('form').on 'click', '.remove_fields', (event) ->
 $(this).prev('input[type=hidden]').val('1')
 $(this).closest('div').remove()
 event.preventDefault()

添加字段(新模板)

 current_index = 0

addText = ->
 html = """
  <div>
  <textarea placeholder="Write something..." name="post[things_attributes][#{current_index}][text]" id="post_things_attributes_#{current_index}_text"></textarea>
  <input type="hidden" name="post[things_attributes][#{current_index}][order]" id="post_things_attributes_#{current_index}_order" value="#{current_index}" />
  <input type="hidden" name="post[thing_attributes][#{current_index}][_destroy]" id="post_things_attributes_#{current_index}__destroy" value="#current_index" />
  <a class="remove_fields" href="#">x</a>
  </div>
 """

 $("#new_post input[type='submit']").before(html)
 current_index += 1

$ ->
  $('#addtext').on('click', addText)


  current_index = 0

addUrl = ->
 html = """
  <div>
  <input placeholder="http://www..." type="url" name="post[things_attributes][#{current_index}][url]" id="post_things_attributes_#{current_index}_url">
  <input type="hidden" name="post[things_attributes][#{current_index}][order]" id="post_things_attributes_#{current_index}_order" value="#{current_index}" />
  <input type="hidden" name="post[thing_attributes][#{current_index}][_destroy]" id="post_things_attributes_#{current_index}__destroy" value="#current_index" />
  <a class="remove_fields" href="#">x</a>
   </div>
   """

  $("#new_post input[type='submit']").before(html)
   current_index += 1

$ ->
  $('#addurl').on('click', addUrl)

添加字段(编辑模板)

     current_index = 0

editText = ->
 html = """
  <div>
  <textarea placeholder="Write something..." name="post[things_attributes][#{current_index}][text]" id="post_things_attributes_#{current_index}_text"></textarea>
  <input type="hidden" name="post[things_attributes][#{current_index}][order]" id="post_things_attributes_#{current_index}_order" value="#{current_index}" />
  <input type="hidden" name="post[thing_attributes][#{current_index}][_destroy]" id="post_things_attributes_#{current_index}__destroy" value="#current_index" />
  <a class="remove_fields" href="#">x</a>
  </div>
 """

 $(".edit_post input[type='submit']").before(html)
 current_index += 1

$ ->
  $('#edittext').on('click', editText)


editUrl = ->
 html = """
  <div>
  <input placeholder="http://www..." type="url" name="post[things_attributes][#{current_index}][url]" id="post_things_attributes_#{current_index}_url">
  <input type="hidden" name="post[things_attributes][#{current_index}][order]" id="post_things_attributes_#{current_index}_order" value="#{current_index}" />
  <input type="hidden" name="post[thing_attributes][#{current_index}][_destroy]" id="post_things_attributes_#{current_index}__destroy" value="#current_index" />
  <a class="remove_fields" href="#">x</a>
  </div>
 """

  $(".edit_post input[type='submit']").before(html)
  current_index += 1

 $ ->
  $('#editurl').on('click', editUrl)

【问题讨论】:

  • 我没有看到任何 Java 代码
  • 我的意思不是按 javascript - 抱歉!
  • 请不要自己编写这个 javascript - 你不会玩得开心(有很多事情需要考虑)。有一个很棒的宝石就是为此而写的:cocoon github.com/nathanvda/cocoon
  • @BroiSatse - 感谢您的评论!我会使用茧宝石
  • 我的nested_form_fields gem 也适用于此:github.com/ncri/nested_form_fields

标签: javascript jquery ruby-on-rails forms ruby-on-rails-4


【解决方案1】:

改变

f.fields_for :thing

到:

f.fields_for :things

因为它是一个 has_many 关联。

编辑:我也刚刚看到您的表单没有在服务器端呈现任何字段。但是,需要添加这些字段,以便 rails 显示您创建的关联:

<%= f.fields_for :things do |ff| %>
  <%= ff.text_field :url %>
  <%= ff.text_area :text %>
<% end %> 

正如其他人的建议:使用现有的解决方案通过 JS 添加关联。这很棘手。试试我的nested_form_fields gem:https://github.com/ncri/nested_form_fields

我不知道茧,但它似乎也是一个很好的解决方案。

【讨论】:

  • 伟大的宝石尼科!非常感谢您的评论 - 完美!
【解决方案2】:

需要检查的几件事:

让 Rails 处理您的路由

new.html.erbedit.html.erb 中,从form_for 中删除url 键,让Rails 找出正确的路径:

<%= form_for @post, html: { multipart: true } do |f| %>    
  <%= f.fields_for :thing do |ff| %>
  <% end %> 
  <%= f.submit %>
<% end %>

更好的是,将这个通用代码放入部分_form.html.erb

# app/views/posts/_form.html.erb
<%= form_for @post, html: { multipart: true } do |f| %>    
  <%= f.fields_for :thing do |ff| %>
  <% end %> 
  <%= f.submit %>
<% end %>

# app/views/posts/new.html.erb | app/views/posts/edit.html.erb
<button id="addtext">Text</button
<button id="addurl">URL</button

<%= render 'form' %>

查看日志

您什么都没有看到这一事实表明存在错误。日志中还有其他内容吗?

$ tail -f log/development.log

还要确保检查任何 javascript 错误(例如,在 Chrome 中,打开检查器工具并查找红色叉号。如果有,请单击它以打开控制台并列出所有错误。

检查缩进

我注意到(但它可能只是粘贴到 SO 编辑器中)是您的第 1 行缩进 (current_index = 0) 在 添加字段(编辑模板) 和 添加字段(新模板) 文件。 CoffeeScript 使用严格的缩进规则:

#    current_index = 0 # <- Your code has extra indentation here
current_index = 0

editText = ->
  html = """
  <div>
   # ...

使用茧

否则,如上面的 cmets 所述,绝对使用cocoon gem 为自己节省大量的样板 JS/CS。我还将simple_form 添加到超级有用的工具列表中。

【讨论】:

  • 非常感谢您的反馈,克里斯 - 很棒的建议!
猜你喜欢
  • 1970-01-01
  • 2016-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多