Skip to content

Commit

Permalink
support nil as model for reform
Browse files Browse the repository at this point in the history
In some cases reform is just used for coercion & validation without any persistence done.
In these cases it was advised to use nil as reform model & to mark all properties as virtual.

this works fine, however fails as .persisted? is called on nil  upon rendering in actionpack-3.2.22.2/lib/action_view/helpers/form_helper.rb:388

...
 as = options[:as]
        action, method = object.respond_to?(:persisted?) && object.persisted? ? [:edit, :put] : [:new, :post]
        options[:html].reverse_merge!(
          :class  => as ? "#{action}_#{as}" : dom_class(object, action),
          :id     => as ? "#{action}_#{as}" : [options[:namespace], dom_id(object, action)].compact.join("_").presence,
          :method => method
        )
...
  • Loading branch information
Pieter Vanmeerbeek committed Jul 15, 2016
1 parent 773a4bf commit c1974e1
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
34 changes: 34 additions & 0 deletions lib/reform/form/active_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,40 @@ def self.included(base)
extend Uber::Delegates
delegates :model, *[:persisted?, :to_key, :to_param, :id] # Uber::Delegates

# Support nil models (aka reform without backed model)
def persisted?
if model.present?
super
else
false
end
end

def to_key
if model.present?
super
else
nil # see http://apidock.com/rails/ActiveModel/Conversion/to_key : nil if no ket attributes
end
end

def to_param
if model.present?
super
else
nil # see http://apidock.com/rails/ActiveModel/Conversion/to_param : nil if not persisted
end
end

def id
if model.present?
super
else
nil
end
end


def to_model # this is called somewhere in FormBuilder and ActionController.
self
end
Expand Down
18 changes: 18 additions & 0 deletions test/active_model_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,24 @@ class Form < Reform::Form
end
end

class ActiveModelWithNilModel < MiniTest::Spec
class SongForm < Reform::Form
include Reform::Form::ActiveModel

property :name, virtual: true
end

let (:form) { SongForm.new(nil) }

it do
form.persisted?.must_equal false
form.to_key.must_equal nil
form.to_param.must_equal nil
form.to_model.must_equal form
form.id.must_equal nil
form.model_name.must_equal form.class.model_name
end
end

class ActiveModelWithCompositionTest < MiniTest::Spec
class HitForm < Reform::Form
Expand Down

0 comments on commit c1974e1

Please sign in to comment.