जब:
<div class="nested-fields">
<div class="kid-fields inline">
<%= f.hidden_field :_destroy, class: 'removable' %>
<%= f.text_field :name, class: 'form-control', placeholder: 'Kid's Name', id: 'kid-input' %>
<div>
<%= link_to_remove_association 'Remove Kid', f %>
</div>
<%= f.fields_for :pets do |pet| %>
<%= render 'pet_fields', f: pet %>
<% end %>
</div>
<div>
<%= link_to_add_association "Add Pet", f, :pets, id: 'add_pet',
'data-association-insertion-method' => 'before' %>
</div>
</div>
यह मेरा _pet_fields.rb फ़ाइल है:
<%= form_for @parent do |f| %>
<% if @parent.errors.any? %>
<div class="alert alert-danger">
<h3><%= pluralize(@student.errors.count, 'Error') %>: </h3>
<ul>
<% @student.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="inline">
<div>
<%= f.fields_for :kids do |kid| %>
<%= render 'kid_fields', f: kid %>
<% end %>
<div>
<%= link_to_add_association "Add Kid", f, :kids, id: 'add_kid',
'data-association-insertion-method' => 'before',
'data-association-insertion-traversal' => 'closest' %>
</div>
<% end %>
</div>
</div>
<div class="form-actions">
<%= f.submit 'Create Parent', class: 'btn btn-primary' %>
</div>
<% end %>
यह मेरा _kid_fields.rb फ़ाइल है: उसकी मेरी _form.html.erb फ़ाइल है मैं "छात्र निकालें" पर क्लिक करता हूं, यह उस लिंक के ऊपर प्रत्येक फ़ील्ड को हटा देता है
यह आपके द्वारा अनुसरण किए जा रहे विशेष रेलस्कास्ट के साथ एक प्रसिद्ध मुद्दा है (यह पुराना है)। एक और here है:
समस्या fields_for
references की child_index
करने के लिए नीचे आता है।
प्रत्येक बार जब आप fields_for
(जो आप उपरोक्त जावास्क्रिप्ट कार्यक्षमता के साथ प्रतिलिपि बना रहे हैं) का उपयोग करते हैं, तो यह id
को बनाए गए फ़ील्ड के प्रत्येक सेट में असाइन करता है। विभिन्न गुणों को अलग करने के लिए ids
params
में उपयोग किया जाता है; उन्हें प्रत्येक फ़ील्ड को HTML "id" property के रूप में भी सौंपा गया है।
इस प्रकार, आपके पास समस्या यह है कि जब भी आप एक नया फ़ील्ड जोड़ते हैं तो आप child_index
को अपडेट नहीं कर रहे हैं, वे सभी समान हैं।और चूंकि आपका link_to_add_fields
सहायक जेएस अपडेट नहीं करता है (आईई आपको बिल्कुल उसी child_index
के साथ फ़ील्ड जोड़ने की अनुमति देता है), इसका मतलब है कि जब भी आप किसी फ़ील्ड को "हटा दें", तो यह उन सभी का चयन करेगा। child_index
(मैं आप नीचे दिए गए एक स्पष्टीकरण दे देंगे)
इस के लिए ठीक स्थापित करने के लिए है।
मैं ईमानदार होने के लिए अपने पुराने सामान को चुनने के बजाय आपको नया कोड देना चाहता हूं। एक बुलाया Cocoon बहुत लोकप्रिय है, हालांकि नहीं एक "प्लग एंड प्ले" समाधान - Rails accepts_nested_attributes_for with f.fields_for and AJAX
जवाहरात जो आपके लिए यह कर रहे हैं:
मैं इस यहाँ (हालांकि यह एक छोटे से पॉलिश किया जा सकता है) के बारे में लिखा कई लोग सोचते हैं कि यह है।
बहरहाल, यह यह सब काम करता है पता करने के लिए, भले ही आप Cocoon
की तरह कुछ का उपयोग करने के निकलूँ सबसे अच्छा है ...
fields_for
समाधान समझने के लिए, आप याद रखना चाहिए कि रेल बनाता है एचटीएमएल रूपों।
आप इसे शायद जानते हैं; कई नहीं करते हैं।
यह महत्वपूर्ण है क्योंकि जब आपको लगता है एचटीएमएल रूपों सभी बाधाओं एचटीएमएल द्वारा लगाए गए का पालन करने के लिए है कि, आप समझ जाएगा कि रेल जादूगर लोगों का एक बहुत लगता है ऐसा नहीं लगता है।
#app/models/student.rb
class Student < ActiveRecord::Base
has_many :teachers
accepts_nested_attributes_for :teachers #-> this is to PASS data, not receive
end
#app/models/teacher.rb
class Teacher < ActiveRecord::Base
belongs_to :student
end
कुछ नोट करना महत्वपूर्ण है कि आपके accepts_nested_attributes_for
माता पिता मॉडल पर होना चाहिए:
एक "नेस्टेड" बनाने के लिए करें जिस तरह से ( बिना जोड़ें/निकालें) कार्यक्षमता इस प्रकार है। यही कारण है, मॉडल आप के लिए डेटा गुजर रहे हैं (नहीं एक डेटा प्राप्त):
नेस्टेड गुण आप माता-पिता
#app/controllers/students_controller.rb
class StudentsController < ApplicationController
def new
@student = Student.new
@student.teachers.build #-> you have to build the associative object
end
def create
@student = Student.new student_params
@student.save
end
private
def student_params
params.require(:student).permit(:x, :y, teachers_attributes: [:z])
end
end
इन के साथ के माध्यम से जुड़े रिकॉर्ड पर विशेषताओं को सहेजने की अनुमति
#app/views/students/new.html.erb
<%= form_for @student do |f| %>
<%= f.fields_for :teachers |teacher| %>
<% # this will replicate for as many times as you've "built" a new teacher object %>
<%= teacher.text_field ... %>
<% end %>
<%= f.submit %>
<% end %>
यह एक स्टेशन है: वस्तुओं बनाया गया है, तो आप उन्हें अपने रूप में उपयोग कर सकें ndard फॉर्म जो आपके नियंत्रक को डेटा भेज देगा, और उसके बाद आपके मॉडल पर। मॉडल में accepts_nested_attributes_for
विधि आश्रित विशेषताओं को आश्रित गुणों को पास करेगी।
-
इस से कोई लेना देना सबसे अच्छी बात एकत्रित फ़ील्ड ऊपर कोड बनाता है के लिए id
को ध्यान में रखना है। मेरे पास हाथ पर कोई उदाहरण नहीं है; यह आपको दिखाना चाहिए कि नेस्टेड फ़ील्ड में teachers_attributes[0][name]
आदि जैसे नाम हैं।
ध्यान देने योग्य महत्वपूर्ण बात यह है कि [0]
- यह child_index है जो आपको आवश्यक कार्यक्षमता में एक महत्वपूर्ण भूमिका निभाता है।
गतिशील
अब गतिशील फार्म के लिए।
पहला भाग अपेक्षाकृत सरल है ... को हटाकर एक फ़ील्ड इसे डीओएम से हटाने का मामला है। हम उस के लिए child_index
#app/models/Student.rb
class Student < ActiveRecord::Base
def self.build #-> non essential; only used to free up controller code
student = self.new
student.teachers.build
student
end
end
#app/controllers/students_controller.rb
class StudentsController < ApplicationController
def new
@student = Student.build
end
def add_teacher
@student = Student.build
render "add_teacher", layout: false
end
def create
@student = Student.new student_params
@student.save
end
private
def student_params
params.require(:student).permit(:x, :y, teachers_attributes: [:z])
end
end
विचारों के लिए
अब (ध्यान दें कि आप partials में अपने फार्म को विभाजित करने के लिए है) का उपयोग कर सकते हैं, इसलिए हम पहले पता करने के लिए बच्चे के सूचकांक सेट करने का तरीका आदि आदि आदि की जरूरत है ...:
#app/views/students/new.html.erb
<%= form_for @student do |f| %>
<%= f.text_field :name %>
<%= render "teacher_fields", locals: {f: f} %>
<%= link_to "Add", "#", id: :add_teacher %>
<%= f.submit %>
<% end %>
#app/views/_teacher_fields.html.erb
<%= f.fields_for :teachers, child_index: Time.now.to_i do |teacher| %>
<%= teacher.text_field ....... %>
<%= link_to "Remove", "#", id: :remove_teacher, data: {i: child_index} %>
<% end %>
#app/views/add_teacher.html.erb
<%= form_for @student, authenticity_token: false do |f| %>
<%= render partial "teacher_fields", locals: {f:f}
<% end %>
यह आप के लिए विभिन्न रूपों आदि, fields_for
सहित प्रस्तुत करना चाहिए। child_index: Time.now.to_i
पर ध्यान दें - यह प्रत्येक fields_for
के लिए एक अद्वितीय आईडी सेट करता है, जो आपको आवश्यकतानुसार प्रत्येक फ़ील्ड के बीच अंतर करने की इजाजत देता है।
इस गतिशील तो जे एस करने के लिए नीचे आता है बनाना:
#config/routes.rb
resources :students do
get :add_teacher, on: :collection #-> url.com/students/get_teacher
end
हमें एक Ajax अनुरोध (एक नए क्षेत्र पाने के लिए) भेजने के लिए अनुमति देता है इस मार्ग का उपयोग करना:
#app/assets/javascripts/.....coffee
$ ->
#Add Teacher
$(document).on "click", "#add_teacher", (e) ->
e.preventDefault();
#Ajax
$.ajax
url: '/students/add_teacher'
success: (data) ->
el_to_add = $(data).html()
$('#subscribers').append(el_to_add)
error: (data) ->
alert "Sorry, There Was An Error!"
#Remove Teacher
$(document).on "click", "#remove_teacher", (e) ->
e.preventDefault();
id = $(this).data("i")
$("input#" + i).remove()
चाहेंगे मैं कक्षा के लिए वही काम करता हूं जैसा मैंने शिक्षक के लिए किया था? मेरे पास कुछ हद तक काम कर रहा है, हालांकि मुझे _do_ को कहीं भी एक बच्चे_इंडेक्स शामिल करने की आवश्यकता है क्योंकि मुझे लगता है कि यह सिर्फ आईडी की बजाय प्रामाणिकता टोकन असाइन कर रहा है। – BB123
तो मैंने [इस उदाहरण] का पालन किया है [https://hackhands.com/building-has_many-model-relationship-form-cocoon/) [कोकून जेम] का उपयोग करके (https://github.com/nathanvda/cocoon) और जब भी मैं "जोड़ें" लिंक पर क्लिक करता हूं, सिवाय इसके कि सबकुछ ठीक से काम कर रहा है, यह सिर्फ एक के बजाय दो फ़ील्ड जोड़ता है। मुझे लगता है कि यह मेरे नियंत्रक के साथ कुछ हो रहा है लेकिन मुझे यकीन नहीं है। मैं किसी भी जेएस या हेल्पर विधियों का उपयोग नहीं कर रहा हूं। मेरी मुख्य चिंता यह है कि खेतों में मुझे एक बच्चा नहीं दे रहा है। इसके बजाय यह मुझे अभी भी दे रहा है जो मुझे लगता है कि एक प्रामाणिकता टोकन (यादृच्छिक संख्याओं का एक गुच्छा) है। @richpeck – BB123
यह संभवतः एक टर्बोलिंक समस्या होगी। पृष्ठ को रीफ्रेश करने का प्रयास करें और इसे दोबारा करने का प्रयास करें - अगर यह दो अनुरोध भेजना जारी रखता है, तो हमें आपके जेएस बाइंडिंग का पता लगाना होगा –