रेल्स: फ़ील्ड_ इंडेक्स के साथ?


102

वहाँ एक विधि (या इसी तरह की कार्यक्षमता को खींचने का तरीका) एक करने के लिए है fields_for_with_index?

उदाहरण:

<% f.fields_for_with_index :questions do |builder, index| %>  
  <%= render 'some_form', :f => builder, :i => index %>
<% end %>

आंशिक रूप से प्रस्तुत किए जाने से यह जानना आवश्यक है कि वर्तमान सूचकांक क्या है fields_for


3
मैं इसे कोर रेल में एक कर देता हूँ ... इस एक मामले के लिए भी आते रहें।
नाथन बर्तराम

जवाबों:


92

यह वास्तव में एक बेहतर दृष्टिकोण होगा, रेल प्रलेखन का अधिक बारीकी से पालन करना:

<% @questions.each.with_index do |question,index| %>
    <% f.fields_for :questions, question do |fq| %>  
        # here you have both the 'question' object and the current 'index'
    <% end %>
<% end %>

प्रेषक: http://railsapi.com/doc/rails-v3.0.4/classes/ActionView/Helpers/FormHelper.html#M006456

उपयोग किए जाने वाले उदाहरण को निर्दिष्ट करना भी संभव है:

  <%= form_for @person do |person_form| %>
    ...
    <% @person.projects.each do |project| %>
      <% if project.active? %>
        <%= person_form.fields_for :projects, project do |project_fields| %>
          Name: <%= project_fields.text_field :name %>
        <% end %>
      <% end %>
    <% end %>
  <% end %>

2
काश, इसके लिए फ़ील्ड_ में कुछ बनाया गया था, लेकिन चूंकि आपका जवाब नहीं है इसलिए मेरा दिन बच गया। धन्यवाद।
एंडर्स किंडबर्ग

1
आप undocumented विकल्प का उपयोग भी कर सकते हैं: फ़ील्ड्स के लिए child_index_for, यदि आपको अधिक नियंत्रण की आवश्यकता है जिस पर सूचकांक प्रदान किया गया है, जैसे: फ़ील्ड_फोर्स (: प्रोजेक्ट्स, प्रोजेक्ट, चाइल्ड_इंडेक्स: इंडेक्स)
एंडर्स किंडबर्ग

यह काम कर रहा है रेल एपीआई लिंक api.rubyonrails.org/classes/ActionView/Helpers/…
Archonic

7
रेल 4.0.2+ उपयोगकर्ताओं को बेन के जवाब की जांच करनी चाहिए क्योंकि सूचकांक अब बिल्डर में बनाया गया है।
नोटपैड

1
@ मर्को तुम राजा सर हो। आपने मेरा दिन बचाया। :-) काश मैं तुम्हें 10 + का जोड़ा दे पाता ......!

157

जवाब काफी सरल है क्योंकि समाधान रेल के भीतर प्रदान किया जाता है। आप f.optionsparams का उपयोग कर सकते हैं । तो, आपके गाया के अंदर _some_form.html.erb,

सूचकांक द्वारा पहुँचा जा सकता है:

<%= f.options[:child_index] %>

आपको कुछ और करने की आवश्यकता नहीं है।


अद्यतन: ऐसा लगता है कि मेरा उत्तर पर्याप्त नहीं था ...

मूल HTML फ़ाइल:

<!-- Main ERB File -->
<% f.fields_for :questions do |builder| %>  
  <%= render 'some_form', :f => builder %>
<% end %>

रेंडर उप-फार्म:

<!-- _some_form.html.erb -->
<%= f.options[:child_index] %>

10
यह यहाँ काम नहीं कर रहा है। आप रेल प्रलेखन लिंक प्रदान कर सकते हैं?
लुकास रेनन

2
@LucasRenan & @graphmeter - कृपया प्रश्न को फिर से पढ़ें, आपको <%= f.options[:child_index] %>अपने रेंडर सब-फॉर्म में कॉल करना होगा (इस मामले में: _some_form.html.erb), मूल को अंतर नहीं करें builder। अधिक स्पष्टीकरण के लिए उत्तर अपडेट किया गया।
शेहरार

1
अजीब, मैं nilउस के लिए मिलता है
bcackerman 19

1
@ शेहर इस रेल में काम कर रहा है 4. लेकिन यह मुझे '1450681048049,1450681050158,1450681056830,1450681141951,1450681219262' जैसे मान दे रहा है। लेकिन मुझे इस रूप में सूचकांक की आवश्यकता है '1,2,3,4,5'। मुझे क्या करना चाहिए?
विडाल

2
प्रतिभाशाली। यह बिल्कुल स्वीकृत उत्तर होना चाहिए।
jeffdill2

100

रेल 4.0.2 के रूप में, एक सूचकांक अब फॉर्मब्यूलेस्ट ऑब्जेक्ट में शामिल है:

https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-fields_for

उदाहरण के लिए:

<%= form_for @person do |person_form| %>
  ...
  <%= person_form.fields_for :projects do |project_fields| %>
    Project #<%= project_fields.index %>
  ...
  <% end %>
  ...
<% end %>

यह काम करता है और लिखने की तुलना में कम है project_fields.options[:child_index]। तो मुझे इस तरह से बेहतर लगता है!
केसी

17

रेल के लिए 4+

<%= form_for @person do |person_form| %>
  <%= person_form.fields_for :projects do |project_fields| %>
    <%= project_fields.index %>
  <% end %>
<% end %>

3 पटरियों के लिए बंदर पैच समर्थन करते हैं

f.indexरेल 3 में काम करने के लिए आपको इस कार्यक्षमता को जोड़ने के लिए अपने प्रोजेक्ट्स इनिशियलाइज़र को एक बंदर पैच जोड़ना होगाfields_for

# config/initializers/fields_for_index_patch.rb

module ActionView
  module Helpers
    class FormBuilder

      def index
        @options[:index] || @options[:child_index]
      end

      def fields_for(record_name, record_object = nil, fields_options = {}, &block)
        fields_options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options?
        fields_options[:builder] ||= options[:builder]
        fields_options[:parent_builder] = self
        fields_options[:namespace] = options[:namespace]

        case record_name
          when String, Symbol
            if nested_attributes_association?(record_name)
              return fields_for_with_nested_attributes(record_name, record_object, fields_options, block)
            end
          else
            record_object = record_name.is_a?(Array) ? record_name.last : record_name
            record_name   = ActiveModel::Naming.param_key(record_object)
        end

        index = if options.has_key?(:index)
                  options[:index]
                elsif defined?(@auto_index)
                  self.object_name = @object_name.to_s.sub(/\[\]$/,"")
                  @auto_index
                end

        record_name = index ? "#{object_name}[#{index}][#{record_name}]" : "#{object_name}[#{record_name}]"
        fields_options[:child_index] = index

        @template.fields_for(record_name, record_object, fields_options, &block)
      end

      def fields_for_with_nested_attributes(association_name, association, options, block)
        name = "#{object_name}[#{association_name}_attributes]"
        association = convert_to_model(association)

        if association.respond_to?(:persisted?)
          association = [association] if @object.send(association_name).is_a?(Array)
        elsif !association.respond_to?(:to_ary)
          association = @object.send(association_name)
        end

        if association.respond_to?(:to_ary)
          explicit_child_index = options[:child_index]
          output = ActiveSupport::SafeBuffer.new
          association.each do |child|
            options[:child_index] = nested_child_index(name) unless explicit_child_index
            output << fields_for_nested_model("#{name}[#{options[:child_index]}]", child, options, block)
          end
          output
        elsif association
          fields_for_nested_model(name, association, options, block)
        end
      end

    end
  end
end

अब तक बेहतर जवाब, उपयोग .indexबहुत क्लीनर है।
लुकास एंड्रेड

7

चेकआउट एक संग्रह का संग्रह प्रस्तुत करना । यदि आपकी आवश्यकता यह है कि एक टेम्पलेट को एक सरणी पर पुनरावृत्त करना होगा और प्रत्येक तत्वों के लिए एक उप टेम्पलेट को प्रस्तुत करना होगा।

<%= f.fields_for @parent.children do |children_form| %>
  <%= render :partial => 'children', :collection => @parent.children, 
      :locals => { :f => children_form } %>
<% end %>

यह "_children.erb" रेंडर करेगा और प्रदर्शन के लिए टेम्पलेट में स्थानीय चर 'बच्चों' को पास करेगा। एक पुनरावृत्ति काउंटर स्वचालित रूप से प्रपत्र के नाम के साथ टेम्पलेट को उपलब्ध कराया जाएगा partial_name_counter। ऊपर के उदाहरण के मामले में, टेम्पलेट को खिलाया जाएगा children_counter

उम्मीद है की यह मदद करेगा।


ऐसा करते समय मुझे "अपरिभाषित स्थानीय चर या विधि 'question_comment_form_counter' मिलता है। question_comment_formमेरा आंशिक नाम होने के नाते ...
शिफफोर्ड

Do है has_many: टिप्पणियों और आप अपने नए उदाहरणों के लिए टिप्पणियों का निर्माण कैसे कर रहे हैं या प्रश्नों की संपादित कार्रवाई 1.times {question.comments.build} करने की कोशिश कर रहे हैं
सैयद असलम

5

मैं ऐसा करने के लिए एक अच्छा तरीका नहीं देख सकता है कि रेल द्वारा प्रदान किए गए तरीकों के माध्यम से, कम से कम -v3.2.14 में नहीं

@ शेहर नसीर विकल्प हैश का संदर्भ देता है जिसका उपयोग समस्या को हल करने के लिए किया जा सकता है लेकिन जहाँ तक मुझे लगता है कि वह जिस तरह से सुझाव देता है, मैं उसे नहीं देख सकता।

मैंने यह किया =>

<%= f.fields_for :blog_posts, {:index => 0} do |g| %>
  <%= g.label :gallery_sets_id, "Position #{g.options[:index]}" %>
  <%= g.select :gallery_sets_id, @posts.collect  { |p| [p.title, p.id] } %>
  <%# g.options[:index] += 1  %>
<% end %>

या

<%= f.fields_for :blog_posts do |g| %>
  <%= g.label :gallery_sets_id, "Position #{g.object_name.match(/(\d+)]/)[1]}" %>
  <%= g.select :gallery_sets_id, @posts.collect  { |p| [p.title, p.id] } %>
<% end %>

मेरे मामले में तीसरे क्षेत्र के लिए g.object_nameइस तरह एक स्ट्रिंग लौटाता है "gallery_set[blog_posts_attributes][2]"तो मैं सिर्फ उस स्ट्रिंग में सूचकांक से मेल खाता हूं और इसका उपयोग करता हूं।


वास्तव में एक कूलर (और शायद क्लीनर?) ऐसा करने के लिए एक मेमने को पारित करने और वेतन वृद्धि के लिए कॉल करना है।

# /controller.rb
index = 0
@incrementer = -> { index += 1}

और देखने में

<%= f.fields_for :blog_posts do |g| %>
  <%= g.label :gallery_sets_id, "Position #{@incrementer.call}" %>
  <%= g.select :gallery_sets_id, @posts.collect  { |p| [p.title, p.id] } %>
<% end %>

1

मुझे पता है कि यह थोड़ा देर से है, लेकिन मुझे हाल ही में यह करना पड़ा कि आप इस तरह से खेतों के सूचकांक को प्राप्त कर सकते हैं

<% f.fields_for :questions do |builder| %>
  <%= render 'some_form', :f => builder, :i => builder.options[:child_index] %>
<% end %>

मुझे आशा है की इससे मदद मिलेगी :)


1

Field_for child_index: 0 में जोड़ा गया

<%= form_for @person do |person_form| %>
  <%= person_form.fields_for :projects, child_index: 0 do |project_fields| %>
    <%= project_fields.index %>
  <% end %>
<% end %>

यह नया सबसे अच्छा जवाब है।
Genkilabs

किसी और को इस के साथ दोहराया क्षेत्रों मिलता है?

0

यदि आप इंडेक्स पर नियंत्रण रखना चाहते हैं तो indexविकल्प देखें

<%= f.fields_for :other_things_attributes, @thing.other_things.build do |ff| %>
  <%= ff.select :days, ['Mon', 'Tues', 'Wed'], index: 2 %>
  <%= ff.hidden_field :special_attribute, 24, index: "boi" %>
<%= end =>

इससे उत्पादन होगा

<select name="thing[other_things_attributes][2][days]" id="thing_other_things_attributes_7_days">
  <option value="Mon">Mon</option>
  <option value="Tues">Tues</option>
  <option value="Wed">Wed</option>
</select>
<input type="hidden" value="24" name="thing[other_things_attributes][boi][special_attribute]" id="thing_other_things_attributes_boi_special_attribute">

यदि फॉर्म जमा किया जाता है, तो params में कुछ ऐसा शामिल होगा

{
  "thing" => {
  "other_things_attributes" => {
    "2" => {
      "days" => "Mon"
    },
    "boi" => {
      "special_attribute" => "24"
    }
  }
}

मुझे अपने बहु-ड्रॉपडाउन को काम करने के लिए सूचकांक विकल्प का उपयोग करना पड़ा। सौभाग्य।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.