2016-02-19 18 views
0

我做了一個表單,用戶可以通過單擊文本或url按鈕動態添加嵌套表單字段。提交表單時,內容將顯示在視圖模板中。但是,當我編輯(&希望然後更新)/posts/id/edit的帖子時,帖子內容不會出現在編輯視圖模板中 - 它是瀏覽器中的空白頁面。Rails嵌套表單 - 編輯動作&edit.html.erb不會顯示錶單或相關文章內容

log of SQL

將非常感謝您的幫助!謝謝!

郵政型號

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.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 %> 

posts.coffee

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}" /> 
</div> 
""" 

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

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


current_index = 0 
+1

你應該有一個叫** edit.html.erb **的視圖 – Turk

+0

道歉 - 我知道,它和new.html.erb模板中的代碼相同。 – domburford

回答

1

有幾個問題與結構:

  1. 您沒有任何字段你form_for
  2. 你定義的字段手動fields_forBIG不)。

的form_for

當你創建一個form_for,Rails使用一個form object從您model獲取數據,並輸出到HTML表單。

這個輸出是在渲染時做的,不管你用JavaScript多少手動起重做不會改變:

<%= form_for @post do |f| %> 
    # you need fields in here 
    <%= f.submit %> 
<% end %> 

調試這個問題的方法是檢查你的頁面的sourceRight-Click > View Source )。如果<form>元素存在,則意味着該form_for方法工作:

enter image description here

此外,請記住form_for是一個輔助的方法。它需要參數並輸出HTML供您使用。這不是魔術。如果它「沒有出現」,就必須有一個合乎邏輯的理由。


fields_for

第二步是你fields_for不會無需任何對象來填充它顯示出來。

當您手動添加新的fields_for字段(基本上是antipattern)時,您也遇到了很大的問題。

你需要做到以下幾點:

#app/controllers/posts_controller.rb 
class PostsController < ApplicationController 
    def edit 
    @post = Post.includes(:things).find(params[:id]) 
    @post.things.build unless @post.things.any? 
    end 
end 

#app/views/posts/edit.html.erb 
<%= form_for @post, url: posts_path, html: { multipart: true } do |f| %> 

    <%= f.fields_for :things do |ff| %> #-> association name (plural) 
    <%= ff.text_area :text, placeholder: "Write Something" %> 
    <% end %> 

    <%= f.submit %> 
<% end %> 

fields_for與您傳遞給form_for父關聯的對象填充。因此,如果您尚未構建任何關聯對象,則需要確保至少構建了一個關聯對象,以便相應地填充字段。


嵌套

最後,你需要認識到,如何動態地添加fieldsfields_for塊。

雖然你的代碼不正確,但這是非常不切實際的。有資源的大片給你指出正確的方向:

  1. RailsCasts Nested Forms
  2. Cocoon寶石(強烈推薦)
  3. NoMethodError within nested model form(我自己的職位)

總之,您需要使用Ruby/Rails來構建您需要的fields_for方法,並使用ajax將它們附加到表單中:

#app/controllers/posts_controller.rb 
class PostsController < ApplicationController 
    def edit 
    @post = Post.includes(:things).find params[:id] 
    @post.things.build unless @post.things.any? 
    respond_to do |format| 
     format.js 
     format.html 
    end 
    end 
end 

#app/views/posts/edit.html.erb 
<%= form_for @post, authenticity_token: !request.xhr? do |f| %> 
    <%= render partial: "things_fields", locals: { f: f } %> 
    <% if !request.xhr? %> 
    <%= button_to "Add Thing", edit_posts_path(@post), method: :get, remote: true %> 
    <%= f.submit %> 
    <% end %> 
<% end %> 

#app/views/posts/_things_fields.html.erb 
<%= f.fields_for :things, child_index: Time.now.to_i do |ff| %> 
    <%= ff.text_area :text, placeholder: "Write Something" %> 
<% end %> 

這將允許你在fields通過JS呼叫追加:

#app/views/posts/edit.js.erb 
$("<%=j render "edit" %>").data().appendTo("form#post); 

這個方法的訣竅是使用child_index: Time.now.to_i(爲每個新追加領域的獨特id)。

-

Long post;如果您希望我專門與您一起閱讀,您就會收到我的電子郵件。