📜 ⬆️ ⬇️

Rails. Adding an element when using nested attributes

Theory


When using nested attributes and fields_for, very often we need to add a new element to the form using javascript.
Guided by the principle of DRY, I recommend using the following solution. I know that this is a well-known technique, but as is usually the case, most of them invent their solutions anyway, and in any case I have not seen such examples in Russian.

I have added the following code to application_helper.rb:
def add_object_link(name, form, object, partial, where) html = render(:partial => partial, :locals => {:form => form}, :object => object) link_to_function name, %{ var new_object_id = new Date().getTime() ; var html = jQuery(#{html.to_json}.replace(/index_to_replace_with_js/g, new_object_id)).hide(); html.appendTo(jQuery("#{where}")).slideDown('slow'); } end 

This is the main helper that generates the html of the new element using javascript, where:
name - link title
form is a form object for form
object - the object of the item to add
partial - the name of the template that generates html to display the added element
where - id of the html container on the page

Example


Suppose we have a rubric (Rubric) in which we need to add some characteristics (Anchor)

app / models / rubric.rb

 class Rubric < ActiveRecord::Base has_many :anchors accepts_nested_attributes_for :anchors, :allow_destroy => true end 

app / models / anchor.rb


 class Anchor < ActiveRecord::Base belongs_to :rubric end 

app / view / admin / rubrics / edit.html.haml

 - form_for @rubric do |f| %h3  != add_object_link('<img src="/images/icons/add.png" />', f, Anchor.new, "anchor", "#anchors") %ul#anchors - @rubric.anchors.each do |anchor| != render :partial => "anchor", :locals => {:form => f, :anchor => anchor} != f.submit(" ") 

app / view / admin / rubrics / _anchor.html.haml

 - raise ArgumentError unless defined?(form) - raise ArgumentError unless defined?(anchor) %li.anchor - form.fields_for :anchors, anchor, :child_index => (anchor.new_record? ? "index_to_replace_with_js" : nil) do |anchor_form| != anchor_form.text_field :title - if anchor_form.object.new_record? %a{:href => "#", :onclick => "jQuery(this).parent('.anchor').remove(); return false;"} %img{:src => "/images/icons/delete.png"} - else != anchor_form.check_box '_destroy' != anchor_form.label '_destroy', '?' 

')
ps I do not pretend to anything, I just want to turn more and more people into my faith =)

Source: https://habr.com/ru/post/116262/


All Articles