Nasıl Raylar ile çok sayıda YENİ öğeler 3.2 yığın ödev teslim etmek
Güzel bir standart durum var. Bir üst nesnenin alt nesneleri bir listesi var. Tabloda satır olarak bütün çocuklar aynı anda düzenleyebilirsiniz nerede sekmeli bir form yapmak istiyorum. Ben de eklemek mümkün veya daha fazla olmak istiyorumyenisatır ve Gönder onları yeni kayıtlar olarak oluşturulacak.
fields_for
iç içe geçmiş kayıtları-çok var ile ilgili alt formları bir dizi işlemek için kullanıyorum, raylar alan adları, örneğin parent[children_attributes][0][fieldname]
, parent[children_attributes][1][fieldname]
ve benzeri üretir.
Bu Raf gibi görünen parametreler bir karma ayrıştırmak neden olur:
{ "parent" => {
"children" => {
"0" => { ... },
"1" => { ... } } }
Zaman geçtiyeni(BM-kalıcı), fields_for
aynı gibi görünen bir alan adı oluşturur nesne:
parent[children_attributes][][fieldname]
Hiç Endeksi []
not.
Buolamazalanları [0]
, [1]
, vb içeren aynı şekilde asılacak. Raf karıştı alır ve yükseltir çünkü
TypeError: expected Array (got Rack::Utils::KeySpaceConstrainedParams)
"", "Emin . yapacağım I. düşünüyor TAMAM ^em>tümalanları [index]
form yerine []
şeklinde kullanın. Ama fields_for
Bu sürekli ikna etmek için nasıl çözemiyorum. Ben, açık bir alan adı bir önek vermek ve nesne bile:
fields_for 'parent[children_attributes][]', child do |f| ...
child
kalıcı olduğu sürece, parent[children_attributes][][fieldname]
yeni kayıtlar için kullanılır bırakarak parent[children_attributes][0][fieldname]
örneğin, olurlar, böylece otomatik olarak kullanılır değiştirir. Bir kez daha, barfs Raf.
Ne diyeceğimi bilmiyorum. Her ne kadar standart Raylar kullanırım yardımcıları fields_for
birden fazla göndermek gibiyenikayıtlar, mevcut kayıtlar ile birlikte, bu parametreler bir dizi olarak ayrıştırılması var, ve tüm kayıtları eksik Kimlikleri var DB yeni kayıt olarak oluşturulacak? Şans ve ben sadece tüm alan adları el ile oluşturmak zorunda mıyım?
CEVAP
Diğerleri de belirttiğim gibi, []
başka bir dizi türü ile bir karma karıştırma çünkü yeni kayıtlar için bir anahtar içermelidir. Fields_for child_index
seçeneği ile ayarlayabilirsiniz.
f.fields_for :items, Item.new, child_index: "NEW_ITEM" # ...
Ben genellikle bu object_id
kullanmak yerine birden fazla yeni öğeler vardır diye benzersiz olduğundan emin olmak için.
item = Item.new
f.fields_for :items, item, child_index: item.object_id # ...
İşte bu soyut yardımcı bir yöntem. Bu hale item_fields
adı ile bir kısmi olduğunu varsayar.
def link_to_add_fields(name, f, association)
new_object = f.object.send(association).klass.new
id = new_object.object_id
fields = f.fields_for(association, new_object, child_index: id) do |builder|
render(association.to_s.singularize "_fields", f: builder)
end
link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})
end
Bu gibi kullanabilirsiniz. Bağımsız değişkenler: bağlantı adı, ana form builder, ve üst model derneğin adı.
<%= link_to_add_fields "Add Item", f, :items %>
Ve burada o bağlantıyı tıklatarak olay dinle, alanları eklemek ve benzersiz bir anahtar vermek için mevcut zaman ile nesne kimliği güncellemek için bazı CoffeeScript.
jQuery ->
$('form').on 'click', '.add_fields', (event) ->
time = new Date().getTime()
regexp = new RegExp($(this).data('id'), 'g')
$(this).before($(this).data('fields').replace(regexp, time))
event.preventDefault()
Bu kod, ücretli bir abonelik gerektirir this RailsCasts Pro episode alınır. Ancak, tam bir çalışma örneği 40 ** serbestçe kullanılabilir.
Güncelleme:child_index
yer tutucu ekleme her zaman gerekli olmadığını işaret etmek istiyorum. Eğer yeni kayıt eklemek, dinamik olarak JavaScript kullanmak istiyorsanız, onları vaktinden kurabilirsiniz:
def new
@project = Project.new
3.times { @project.items.build }
end
<%= f.fields_for :items do |builder| %>
Raylar otomatik olarak sadece çalışması gerekir, böylece yeni kayıtlar için bir dizin ekler.
Nasıl ActiveRecord/Raylar ile bir sorg...
Nasıl yeni bir Rails uygulaması oluştu...
Nasıl parametreleri raylar varsa test ...
Rspec, Raylar: nasıl denetleyicileri ö...
Nasıl yeni öğeler eklemek için boş bir...