Мое приложение имеет местоположение, каждое местоположение имеет много 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, "ips", "<p class=\"fields\">\n <input type=\"text\" name=\"location[ips_attributes][new_ips][address]\" id=\"location_ips_attributes_new_ips_address\" />\n<\/p>\n")" href="#">add new IP address</a>
</p>