Skip to content

Instantly share code, notes, and snippets.

@bkildow
Last active January 15, 2017 16:01
Show Gist options
  • Save bkildow/0c1bd0db8d1e4acdbb1c to your computer and use it in GitHub Desktop.
Save bkildow/0c1bd0db8d1e4acdbb1c to your computer and use it in GitHub Desktop.
Reform 1.2.6 nested form (with support for cocoon gem)
# app/forms/graduation_form.rb
require 'concerns/nested_form'
class GraduationForm < Reform::Form
# Needed for correct behavior of virtual attributes, see https://github.com/apotonick/reform/issues/75
reform_2_0!
model :response
collection :minor_responses, populate_if_empty: MinorResponse do
include Reform::NestedForm
property :minor_name
# only save this if minor_name isn't blank
reject_if_blank :minor_name
end
end
# app/forms/concerns/nested_form.rb
# Helps facilitates nested forms. loosely based on: https://github.com/apotonick/reform/issues/86#issuecomment-73918238
# Adds the ability to exclude saving if a particular field is blank, and helper methods to make cocoon gem work.
module Reform
module NestedForm
extend ActiveSupport::Concern
included do
property :id, virtual: true
property :_destroy, virtual: true
@reject_field = []
end
def sync_hash(options)
if fields._destroy == '1' || reject_fields?
model.mark_for_destruction
end
super(options)
end
def new_record?
model.new_record?
end
def marked_for_destruction?
model.marked_for_destruction?
end
def reject_fields?
self.class.reject_field.any? { |f| fields[f].blank? }
end
class_methods do
def reject_if_blank(field)
@reject_field << field
end
def reject_field
@reject_field
end
end
end
end
# app/models/response.rb
class Response < ActiveRecord::Base
# autosave: true is needed to get mark_for_destruction
has_many :minor_responses, dependent: :destroy, autosave: true
end
@lucaspiller
Copy link

Here is an update that works with Reform 2.2.1:

https://gist.github.com/lucaspiller/615f09bb525a14163921fd56b4b8e611

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment