Несколько типов полей для вложенной формы - PullRequest
0 голосов
/ 04 ноября 2018

Мое приложение имеет местоположение, каждое местоположение имеет много IP-адресов. Используя соответствующий эпизод railscasts (http://railscasts.com/episodes/197-nested-model-form-part-2) Я построил форму location, которая включает в себя список ip s и возможность добавлять новые. Каждый ip имеет свой text_field, сгенерированный формой.

Дело в том, что я хочу, чтобы существующие ip s отображались как label s, а не как редактируемые текстовые поля, что-то вроде этого:

  • существует (только для чтения)

  • существует (только для чтения)

  • существует (только для чтения)

новая ссылка

и после нажатия на ссылку добавляется редактируемое текстовое поле. Есть идеи?


Модель

location.rb

class Ip < ActiveRecord::Base
  belongs to :location
  validates_uniqueness_of :address
  [...]
end

ip.rb

class Location < ActiveRecord::Base
  has_many :ips
  accepts_nested_attributes_for :ips
  [...]
end

Контроллер

class LocationsController < ApplicationController
  [...]
  def location_params
    params.require(:location).permit(:name, ips_attributes: [:id, :address])
  end
end

Helper

module ApplicationHelper
  [...]  
  def link_to_add_fields(name, f, association)
    new_obj = f.object.class.reflect_on_association(association).klass.new
    fields = f.fields_for(association, new_obj, :child_index => "new_#{association}") do |builder|
      render(association.to_s.singularize + "_fields", :f => builder)
    end
    link_to name, "#", onclick: "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")"
  end
end

Просмотры :

/ места / _form.html.erb

<header>
  <script>
    function add_fields(link, association, content) {
      var new_id = new Date().getTime();
      var regexp = new RegExp("new_" + association, "g")
      $(link).parent().before(content.replace(regexp, new_id));
    }
  </script>
</header>
<%= form_for @location do |f| %>
  [...]
  <%= f.label :ips, t('location.ips') %>
  <%= f.fields_for :ips do |builder| %>
    <%= redner "ip_fields", f: builder %>
  <% end %>
  <p>
    <%= link_to_add_fields t('location.add_ip'), f, :ips %>
  </p>
  [...]
<% end %>

_ip_fields.html.erb

<p class="fields">
  <%= f.text_field :address %>
</p>

Соответствующий HTML:

  <label for="location_ips">Addresses</label>

    <p class="fields">
    <input type="text" value="1.2.3.5" name="location[ips_attributes][0][address]" id="location_ips_attributes_0_address" />
</p>

<input type="hidden" value="19" name="location[ips_attributes][0][id]" id="location_ips_attributes_0_id" />
    <p class="fields">
    <input type="text" value="2.3.4.5" name="location[ips_attributes][1][address]" id="location_ips_attributes_1_address" />
</p>

<input type="hidden" value="20" name="location[ips_attributes][1][id]" id="location_ips_attributes_1_id" />
    <p class="fields">
    <input type="text" value="3.4.5.6" name="location[ips_attributes][2][address]" id="location_ips_attributes_2_address" />
</p>

<input type="hidden" value="21" name="location[ips_attributes][2][id]" id="location_ips_attributes_2_id" />
    <p class="fields">
    <input type="text" value="9.9.9.9" name="location[ips_attributes][3][address]" id="location_ips_attributes_3_address" />
</p>

<input type="hidden" value="22" name="location[ips_attributes][3][id]" id="location_ips_attributes_3_id" />
  <p>
    <a onclick="add_fields(this, &quot;ips&quot;, &quot;&lt;p class=\&quot;fields\&quot;&gt;\n  &lt;input type=\&quot;text\&quot; name=\&quot;location[ips_attributes][new_ips][address]\&quot; id=\&quot;location_ips_attributes_new_ips_address\&quot; /&gt;\n&lt;\/p&gt;\n&quot;)" href="#">add new IP address</a>
    </p>

1 Ответ

0 голосов
/ 05 ноября 2018

Что ж, это не очень красиво (логика в представлении не рекомендуется), но оно обеспечивает решение, которое я хотел: дополнительный параметр в вспомогательном методе, чтобы сигнализировать о немаркированном поле, затем рефакторинг частичного условного выражения в существование этой переменной

помощник:

module ApplicationHelper
  [...]  
  def link_to_add_fields(name, f, association)
    new_obj = f.object.class.reflect_on_association(association).klass.new
    fields = f.fields_for(association, new_obj, :child_index => "new_#{association}") do |builder|
      render(association.to_s.singularize + "_fields", :f => builder, labelled: false)
    end
    link_to name, "#", onclick: "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")"
  end
end

_ip_fields.html.erb

<p class="fields">
  <% if (defined? labelled) %>
    <%= f.text_field :address %>
  <% else %>
    <%= f.label :address, f.object.address %>
  <% end %>
</p>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...