freeform 0.0.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. data/.gitignore +8 -17
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +150 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +31 -43
  6. data/Rakefile +32 -1
  7. data/freeform.gemspec +22 -15
  8. data/lib/freeform/builder/builder_mixin.rb +111 -0
  9. data/lib/freeform/builder/builders.rb +32 -0
  10. data/lib/freeform/builder/engine.rb +14 -0
  11. data/lib/freeform/builder/view_helper.rb +56 -0
  12. data/lib/freeform/form/form_input_key.rb +1 -1
  13. data/lib/freeform/form/nested.rb +17 -55
  14. data/lib/freeform/form/property.rb +82 -42
  15. data/lib/freeform/form/validation.rb +38 -11
  16. data/lib/freeform/form.rb +24 -27
  17. data/lib/freeform/version.rb +1 -1
  18. data/lib/freeform.rb +4 -0
  19. data/lib/generators/freeform/install_generator.rb +17 -0
  20. data/lib/tasks/freeform_tasks.rake +4 -0
  21. data/spec/acceptance_spec.rb +261 -155
  22. data/spec/builder/builder_spec.rb +215 -0
  23. data/spec/builder/view_helper_spec.rb +97 -0
  24. data/spec/dummy/README.rdoc +28 -0
  25. data/spec/dummy/Rakefile +6 -0
  26. data/spec/dummy/app/assets/images/.keep +0 -0
  27. data/spec/dummy/app/assets/javascripts/application.js +5 -0
  28. data/spec/dummy/app/assets/javascripts/jquery.js +9404 -0
  29. data/spec/dummy/app/assets/javascripts/jquery_events_test.js +19 -0
  30. data/spec/dummy/app/assets/javascripts/projects.js +2 -0
  31. data/spec/dummy/app/assets/javascripts/prototype.js +6082 -0
  32. data/spec/dummy/app/assets/javascripts/prototype_events_test.js +20 -0
  33. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  34. data/spec/dummy/app/assets/stylesheets/companies.css +4 -0
  35. data/spec/dummy/app/assets/stylesheets/projects.css +4 -0
  36. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  37. data/spec/dummy/app/controllers/companies_controller.rb +5 -0
  38. data/spec/dummy/app/controllers/projects_controller.rb +11 -0
  39. data/spec/dummy/app/forms/milestone_form.rb +4 -0
  40. data/spec/dummy/app/forms/project_form.rb +11 -0
  41. data/spec/dummy/app/forms/task_form.rb +10 -0
  42. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  43. data/spec/dummy/app/mailers/.keep +0 -0
  44. data/spec/dummy/app/models/.keep +0 -0
  45. data/spec/dummy/app/models/company.rb +5 -0
  46. data/spec/dummy/app/models/milestone.rb +6 -0
  47. data/spec/dummy/app/models/project.rb +9 -0
  48. data/spec/dummy/app/models/project_task.rb +3 -0
  49. data/spec/dummy/app/models/task.rb +7 -0
  50. data/spec/dummy/app/views/companies/new.html.erb +16 -0
  51. data/spec/dummy/app/views/layouts/application.html.erb +19 -0
  52. data/spec/dummy/app/views/projects/new.html.erb +13 -0
  53. data/spec/dummy/app/views/projects/without_intermediate_inputs.html.erb +11 -0
  54. data/spec/dummy/bin/bundle +3 -0
  55. data/spec/dummy/bin/rails +4 -0
  56. data/spec/dummy/bin/rake +4 -0
  57. data/spec/dummy/config/application.rb +35 -0
  58. data/spec/dummy/config/boot.rb +5 -0
  59. data/spec/dummy/config/database.yml +25 -0
  60. data/spec/dummy/config/environment.rb +5 -0
  61. data/spec/dummy/config/environments/development.rb +29 -0
  62. data/spec/dummy/config/environments/production.rb +80 -0
  63. data/spec/dummy/config/environments/test.rb +36 -0
  64. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  65. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  66. data/spec/dummy/config/initializers/inflections.rb +16 -0
  67. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  68. data/spec/dummy/config/initializers/secret_token.rb +13 -0
  69. data/spec/dummy/config/initializers/session_store.rb +3 -0
  70. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  71. data/spec/dummy/config/locales/en.yml +23 -0
  72. data/spec/dummy/config/routes.rb +5 -0
  73. data/spec/dummy/config.ru +4 -0
  74. data/spec/dummy/db/migrate/20110710143903_initial_tables.rb +38 -0
  75. data/spec/dummy/db/schema.rb +43 -0
  76. data/spec/dummy/db/test.sqlite3 +0 -0
  77. data/spec/dummy/lib/assets/.keep +0 -0
  78. data/spec/dummy/log/.keep +0 -0
  79. data/spec/dummy/log/development.log +0 -0
  80. data/spec/dummy/log/test.log +39736 -0
  81. data/spec/dummy/public/404.html +58 -0
  82. data/spec/dummy/public/422.html +58 -0
  83. data/spec/dummy/public/500.html +57 -0
  84. data/spec/dummy/public/favicon.ico +0 -0
  85. data/spec/dummy/tmp/cache/assets/C54/850/sprockets%2Fd484f47085686f151320ff7248bb5105 +0 -0
  86. data/spec/dummy/tmp/cache/assets/C76/160/sprockets%2F49c594d143212b346d11f1ecf9358103 +0 -0
  87. data/spec/dummy/tmp/cache/assets/C99/4D0/sprockets%2F5e30a6b911437f1428dc32c3ae182123 +0 -0
  88. data/spec/dummy/tmp/cache/assets/C99/7D0/sprockets%2F79513e6956e0ee8624976e041fd5636d +0 -0
  89. data/spec/dummy/tmp/cache/assets/CAA/C90/sprockets%2F1e6c8ee1258009385ccf5b84015424b3 +0 -0
  90. data/spec/dummy/tmp/cache/assets/CB2/CB0/sprockets%2F11cc8d161d71a716dd36f16849d90870 +0 -0
  91. data/spec/dummy/tmp/cache/assets/CB7/7F0/sprockets%2Fac97b043470f6fcc925c352f16956643 +0 -0
  92. data/spec/dummy/tmp/cache/assets/CBA/680/sprockets%2F912d84e091e5f2190b1ab7926de19679 +0 -0
  93. data/spec/dummy/tmp/cache/assets/CC7/430/sprockets%2F48e99a3e16ba3e65749e009d82546f94 +0 -0
  94. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  95. data/spec/dummy/tmp/cache/assets/CDB/8A0/sprockets%2Faed2a2575c376263c26e93b56b57051d +0 -0
  96. data/spec/dummy/tmp/cache/assets/CF1/E80/sprockets%2F7735295e1e3085f2e1dc29d59a45e8e6 +0 -0
  97. data/spec/dummy/tmp/cache/assets/D0F/E60/sprockets%2F1123d9a479fdf5c2b8415087e2a43ec6 +0 -0
  98. data/spec/dummy/tmp/cache/assets/D1F/A10/sprockets%2F60317e62cb324bfd9987e8da9636fd06 +0 -0
  99. data/spec/dummy/tmp/cache/assets/D25/E20/sprockets%2F29ba1a4a2b611731334f54abb9e5b5d1 +0 -0
  100. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  101. data/spec/dummy/tmp/cache/assets/D35/760/sprockets%2F49e26620c5c743ac4cdab7703f54db06 +0 -0
  102. data/spec/dummy/tmp/cache/assets/D49/870/sprockets%2F90896142645585acc8baf56ad57e3afb +0 -0
  103. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  104. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  105. data/spec/dummy/tmp/cache/assets/D62/F00/sprockets%2F6ac03a007f26b1c18ed3d53498ad3eb8 +0 -0
  106. data/spec/dummy/tmp/cache/assets/D79/BC0/sprockets%2F85a1db977361cc5130fcefb4637ff67e +0 -0
  107. data/spec/dummy/tmp/cache/assets/D87/1F0/sprockets%2F61c9ceafb877fb740c67416ff6f782a9 +0 -0
  108. data/spec/dummy/tmp/cache/assets/DA8/900/sprockets%2Fde7a2b3987b89b9d9afb268ce4204a4a +0 -0
  109. data/spec/dummy/tmp/cache/assets/DAD/4F0/sprockets%2F765acd1bf68dc90f7d3e61da78b1e659 +0 -0
  110. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  111. data/spec/dummy/tmp/cache/assets/E03/3F0/sprockets%2F82b37ae9eccec44c1ef44cfdd07d8534 +0 -0
  112. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  113. data/spec/dummy/tmp/cache/assets/E0A/CA0/sprockets%2F7fe72ac1c0db1a7e8e7f59cf25e8a39e +0 -0
  114. data/spec/dummy/tmp/cache/assets/E20/9B0/sprockets%2F2fa6cd86b1af7bda41f5b7921cdadf10 +0 -0
  115. data/spec/dummy/tmp/cache/assets/E3A/A60/sprockets%2F7c72c96cfc66454caf5fc8ca0fedd4f3 +0 -0
  116. data/spec/dummy/tmp/cache/assets/E54/400/sprockets%2Fd0cbc16cc37efcf9dc41f242b5dbbf81 +0 -0
  117. data/spec/dummy/tmp/cache/assets/EB7/AB0/sprockets%2F801d29a5debdbfbfb4eef14d70d9bcdb +0 -0
  118. data/spec/dummy/tmp/cache/assets/F48/5E0/sprockets%2F26cd6ffcffbebbe2fd6cd1a8f0c2debc +0 -0
  119. data/spec/form/nested_spec.rb +75 -61
  120. data/spec/form/property_spec.rb +167 -14
  121. data/spec/form/validation_spec.rb +46 -23
  122. data/spec/javascript_spec.rb +60 -0
  123. data/spec/persistence_spec.rb +608 -0
  124. data/spec/spec_helper.rb +18 -2
  125. data/vendor/assets/javascripts/jquery_freeform.js +120 -0
  126. data/vendor/assets/javascripts/jquery_nested_form.js +0 -0
  127. data/vendor/assets/javascripts/prototype_freeform.js +69 -0
  128. data/vendor/assets/javascripts/prototype_nested_form.js +0 -0
  129. metadata +341 -3
@@ -1,5 +1,3 @@
1
- require 'freeform/form/property'
2
-
3
1
  module FreeForm
4
2
  module Nested
5
3
  def self.included(base)
@@ -9,55 +7,18 @@ module FreeForm
9
7
  module ClassMethods
10
8
  # Nested Forms
11
9
  #------------------------------------------------------------------------
12
- attr_accessor :nested_forms
10
+ attr_accessor :nested_forms
13
11
 
14
- def nested_form(attribute, options={}, &block)
15
- # Specify the class method on which we're defining the initializer for this form.
16
- parent_class = self
17
- initializer_method = options[:class_initializer]
18
- unless initializer_method.nil?
19
- define_singleton_method(:"#{initializer_method}") do
20
- var = instance_variable_get(:"@#{initializer_method}")
21
- var ||= {}
22
- var
23
- end
24
-
25
- define_singleton_method(:"#{initializer_method}=") do |val|
26
- instance_variable_set(:"@#{initializer_method}", val)
27
- end
28
- end
12
+ def nested_form(attribute, options={})
13
+ nested_form_class = options[:class]
14
+ @nested_forms ||= {}
15
+ @nested_forms.merge!({:"#{attribute}" => nested_form_class})
29
16
 
30
17
  # Define an attr_accessor for the parent class to hold this attribute
31
18
  declared_model(attribute)
32
19
 
33
- # Define the new class, and set it up with a new name
34
- nested_form_class = Class.new(FreeForm::Form) do
35
- include FreeForm::Property
36
- self.instance_eval(&block)
37
-
38
- define_singleton_method(:default_initializer) do
39
- unless initializer_method.nil?
40
- method = parent_class.send(initializer_method)
41
- if method.is_a? Proc
42
- method.call
43
- else
44
- method
45
- end
46
- end
47
- end
48
-
49
- def initialize(p={}, *args)
50
- p = self.class.default_initializer.merge(p)
51
- super(p, *args)
52
- end
53
- end
54
- self.const_set("#{attribute.to_s.camelize}Form", nested_form_class)
55
-
56
- @nested_forms ||= {}
57
- @nested_forms.merge!({:"#{attribute}" => nested_form_class})
58
-
59
20
  # Defined other methods
60
- define_nested_model_methods(attribute, nested_form_class)
21
+ define_nested_model_methods(attribute, nested_form_class, options)
61
22
 
62
23
  # Setup Handling for nested attributes
63
24
  define_nested_attribute_methods(attribute, nested_form_class)
@@ -65,18 +26,10 @@ module FreeForm
65
26
  alias_method :has_many, :nested_form
66
27
  alias_method :has_one, :nested_form
67
28
 
68
- # Supporting Methods
69
- #------------------------------------------------------------------------
70
- def reflect_on_association(key, *args)
71
- reflection = OpenStruct.new
72
- reflection.klass = self.nested_forms[key]
73
- reflection
74
- end
75
-
76
29
  protected
77
30
  # Defining Helper Methods For Models
78
31
  #------------------------------------------------------------------------
79
- def define_nested_model_methods(attribute, form_class)
32
+ def define_nested_model_methods(attribute, form_class, options={})
80
33
  singularized_attribute = attribute.to_s.singularize.to_s
81
34
 
82
35
  # Example: form.addresses will return all nested address forms
@@ -85,9 +38,18 @@ module FreeForm
85
38
  end
86
39
 
87
40
  # Example: form.build_addresses (optional custom initializer)
88
- define_method(:"build_#{attribute}") do |initializer={}|
41
+ define_method(:"build_#{attribute}") do |initializer=nil|
42
+ # Builder object
43
+ parent_object = self
44
+
89
45
  # Get correct class
90
46
  form_class = self.class.nested_forms[:"#{attribute}"]
47
+
48
+ # Default Initializer
49
+ if options[:default_initializer]
50
+ initializer ||= instance_eval(&options[:default_initializer])
51
+ end
52
+ initializer ||= {}
91
53
 
92
54
  # Build new model
93
55
  form_model = form_class.new(initializer)
@@ -13,6 +13,10 @@ module FreeForm
13
13
  @models ||= []
14
14
  end
15
15
 
16
+ def child_models
17
+ @child_models ||= []
18
+ end
19
+
16
20
  def declared_model(name, opts={})
17
21
  @models ||= []
18
22
  @models << name
@@ -27,73 +31,109 @@ module FreeForm
27
31
  end
28
32
  alias_method :form_models, :declared_models
29
33
 
34
+ def child_model(name, opts={}, &block)
35
+ @models ||= []
36
+ @models << name
37
+ @child_models ||= []
38
+ @child_models << name
39
+ attr_accessor name
40
+ define_method("initialize_#{name}") do
41
+ instance_variable_set("@#{name}", instance_eval(&block))
42
+ end
43
+ end
44
+
30
45
  # Properties
31
46
  #------------------------------------------------------------------------
32
- def ignored_blank_params
33
- @ignored_blank_params ||= []
47
+ def property_mappings
48
+ # Take the form of {:property => {:model => model, :field => field, :ignore_blank => false}}
49
+ @property_mappings ||= Hash.new
34
50
  end
35
51
 
36
52
  def allow_destroy_on_save
37
53
  # Define _destroy method for marked-for-destruction handling
38
54
  attr_accessor :_destroy
39
- alias_method :marked_for_destruction, :_destroy
55
+ define_method(:_destroy=) do |value|
56
+ false_values = [nil, 0 , false, "0", "false"]
57
+ @_destroy = !(false_values.include?(value))
58
+ end
59
+ alias_method :marked_for_destruction?, :_destroy
60
+ define_method(:mark_for_destruction) do
61
+ @_destroy = true
62
+ end
40
63
  end
41
64
 
42
65
  def property(attribute, options={})
43
- if options[:on]
44
- def_delegator options[:on], attribute
45
- def_delegator options[:on], "#{attribute}=".to_sym
46
- else
66
+ @property_mappings ||= Hash.new
67
+ model = options[:on] ? options [:on] : :self
68
+ field = options[:as] ? options[:as] : attribute.to_sym
69
+ ignore_blank = options[:ignore_blank] ? options[:ignore_blank] : false
70
+ @property_mappings.merge!({field => {:model => model, :field => attribute.to_sym, :ignore_blank => ignore_blank}})
71
+
72
+ if model == :self
47
73
  attr_accessor attribute
74
+ else
75
+ define_method("#{field}") do
76
+ send("#{model}").send("#{attribute}")
77
+ end
78
+
79
+ define_method("#{field}=") do |value|
80
+ send("#{model}").send("#{attribute}=", value)
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ attr_accessor :parent_form
87
+
88
+ class DateParamsFilter
89
+ def call(params)
90
+ date_attributes = {}
91
+
92
+ params.each do |attribute, value|
93
+ if value.is_a?(Hash)
94
+ call(value) # TODO: #validate should only handle local form params.
95
+ elsif matches = attribute.match(/^(\w+)\(.i\)$/)
96
+ date_attribute = matches[1]
97
+ date_attributes[date_attribute] = params_to_date(
98
+ params.delete("#{date_attribute}(1i)"),
99
+ params.delete("#{date_attribute}(2i)"),
100
+ params.delete("#{date_attribute}(3i)")
101
+ )
102
+ end
103
+ end
104
+ params.merge!(date_attributes)
105
+ end
106
+
107
+ private
108
+ def params_to_date(year, month, day)
109
+ day ||= 1 # FIXME: is that really what we want? test.
110
+ begin # TODO: test fails.
111
+ return Date.new(year.to_i, month.to_i, day.to_i)
112
+ rescue ArgumentError => e
113
+ return nil
48
114
  end
49
- @ignored_blank_params ||= []
50
- @ignored_blank_params << attribute if options[:ignore_blank]
51
115
  end
52
116
  end
53
117
 
54
118
  def assign_params(params)
55
- filter_dates(params)
119
+ DateParamsFilter.new.call(params)
56
120
  params.each_pair do |attribute, value|
57
- self.send :"#{attribute}=", value unless ignore?(attribute, value)
121
+ assign_attribute(attribute, value)
58
122
  end
59
123
  self
60
124
  end
61
125
  alias_method :assign_attributes, :assign_params
62
126
  alias_method :populate, :assign_params
63
127
  alias_method :fill, :assign_params
64
-
65
- def ignore?(attribute, value)
66
- ignored_if_blank = self.class.ignored_blank_params
67
- return (ignored_if_blank.include?(attribute.to_sym) && value.blank?)
68
- end
69
128
 
70
- private
71
- #TODO: This should be its own model
72
- def filter_dates(params)
73
- date_attributes = {}
74
- params.each do |attribute, value|
75
- if attribute.to_s.include?("(1i)") || attribute.to_s.include?("(2i)") || attribute.to_s.include?("(3i)")
76
- date_attribute = attribute.to_s.gsub(/(\(.*\))/, "")
77
- date_attributes[date_attribute.to_sym] = params_to_date(
78
- params.delete("#{date_attribute}(1i)"),
79
- params.delete("#{date_attribute}(2i)"),
80
- params.delete("#{date_attribute}(3i)")
81
- )
82
- end
83
- end
84
- params.merge!(date_attributes)
129
+ private
130
+ def assign_attribute(attribute, value)
131
+ self.send :"#{attribute}=", value unless ignore?(attribute, value)
85
132
  end
86
-
87
- def params_to_date(year, month, day)
88
- day ||= 1
89
- begin
90
- return Date.new(year.to_i, month.to_i, day.to_i)
91
- rescue => e
92
- return nil
93
- end
133
+
134
+ def ignore?(attribute, value)
135
+ mapping = self.class.property_mappings[attribute.to_sym]
136
+ return (mapping[:ignore_blank] && value.blank?) unless mapping.nil?
94
137
  end
95
138
  end
96
-
97
- #Instance Methods
98
- #----------------------------------------------------------------------------
99
139
  end
@@ -2,6 +2,7 @@ module FreeForm
2
2
  module Validation
3
3
  def self.included(base)
4
4
  base.extend(ClassMethods)
5
+ extend FreeForm::Property
5
6
  end
6
7
 
7
8
  module ClassMethods
@@ -10,25 +11,51 @@ module FreeForm
10
11
  end
11
12
  end
12
13
 
13
- protected
14
+ protected
14
15
  def model_validity
15
- model_validity = true
16
- self.class.models.each do |form_model|
16
+ self.class.models.each do |form_model|
17
17
  if send(form_model).is_a?(Array)
18
- send(form_model).each { |model| model_validity = validate_and_append_errors(model) && model_validity }
18
+ # If it's an array, we're dealing with nested forms
19
+ errors.add(:base, "has invalid nested forms") unless validate_nested_forms(send(form_model))
19
20
  else
20
- model_validity = validate_and_append_errors(send(form_model)) && model_validity
21
+ # Otherwise, validate the form object
22
+ validate_form_model(form_model)
21
23
  end
22
24
  end
23
- return model_validity
24
25
  end
25
26
 
26
- def validate_and_append_errors(model)
27
- unless model.valid?
28
- model.errors.each { |error, message| self.errors.add(error, message) }
29
- return false
27
+ private
28
+ def validate_nested_forms(form_array)
29
+ form_validity = true
30
+ form_array.each do |model|
31
+ form_validity = false unless model.valid?
30
32
  end
31
- return true
33
+ form_validity
34
+ end
35
+
36
+ def validate_form_model(form_model)
37
+ model = send(form_model)
38
+ append_errors(form_model)
39
+ return model.valid?
40
+ end
41
+
42
+ def append_errors(form_model)
43
+ model = send(form_model)
44
+ model.valid?
45
+ model.errors.each do |error, message|
46
+ if find_form_field_from_model_field(form_model, error)
47
+ self.errors.add(find_form_field_from_model_field(form_model, error), message)
48
+ end
49
+ end
50
+ end
51
+
52
+ def find_form_field_from_model_field(model, field)
53
+ self.class.property_mappings.each_pair do |property, attributes|
54
+ if (attributes[:model] == model.to_sym) && (attributes[:field] == field.to_sym)
55
+ return property
56
+ end
57
+ end
58
+ return false
32
59
  end
33
60
  end
34
61
  end
data/lib/freeform/form.rb CHANGED
@@ -22,51 +22,48 @@ module FreeForm
22
22
  # Instance Methods
23
23
  #----------------------------------------------------------------------------
24
24
  # Required for ActiveModel
25
- def persisted?
26
- false
27
- end
25
+ def persisted?; false end
28
26
 
29
27
  def initialize(h={})
30
28
  h.each {|k,v| send("#{k}=",v)}
29
+ initialize_child_models
31
30
  end
32
31
 
33
32
  def save
34
33
  return false unless valid?
34
+
35
35
  self.class.models.each do |form_model|
36
- if send(form_model).is_a?(Array)
37
- send(form_model).each { |model| return model.save }
38
- else
39
- if marked_for_destruction?
40
- send(form_model).destroy
41
- else
42
- return false unless send(form_model).save
43
- end
44
- end
36
+ model = send(form_model)
37
+ model.is_a?(Array) ? model.each { |m| m.save } : save_or_destroy(model)
45
38
  end
46
- return true
47
39
  end
48
40
 
49
41
  def save!
50
42
  raise FreeForm::FormInvalid, "form invalid." unless valid?
43
+
51
44
  self.class.models.each do |form_model|
52
- if send(form_model).is_a?(Array)
53
- send(form_model).each { |model| model.save! }
54
- else
55
- if marked_for_destruction?
56
- send(form_model).destroy
57
- else
58
- send(form_model).save!
59
- end
60
- end
45
+ model = send(form_model)
46
+ model.is_a?(Array) ? model.each { |m| m.save! } : save_or_destroy!(model)
61
47
  end
62
48
  end
63
49
 
50
+ private
51
+ def initialize_child_models
52
+ self.class.child_models.each do |c|
53
+ send("initialize_#{c}")
54
+ end
55
+ end
56
+
57
+ def save_or_destroy(model)
58
+ marked_for_destruction? ? model.destroy : model.save
59
+ end
60
+
61
+ def save_or_destroy!(model)
62
+ marked_for_destruction? ? model.destroy : model.save!
63
+ end
64
+
64
65
  def marked_for_destruction?
65
- if self.respond_to?(:_destroy)
66
- return self._destroy
67
- else
68
- return false
69
- end
66
+ respond_to?(:_destroy) ? _destroy : false
70
67
  end
71
68
  end
72
69
  end
@@ -1,3 +1,3 @@
1
1
  module Freeform
2
- VERSION = "0.0.4"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/freeform.rb CHANGED
@@ -2,4 +2,8 @@ require 'freeform/version'
2
2
  require 'freeform/form'
3
3
 
4
4
  if defined?(Rails) # Where to include Rails specific modules...
5
+ require 'freeform/builder/builder_mixin'
6
+ require 'freeform/builder/builders'
7
+ require 'freeform/builder/view_helper'
8
+ require 'freeform/builder/engine'
5
9
  end
@@ -0,0 +1,17 @@
1
+ module FreeForm
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ def self.source_root
5
+ File.expand_path('../../../../vendor/assets/javascripts', __FILE__)
6
+ end
7
+
8
+ def copy_jquery_file
9
+ if File.exists?('public/javascripts/prototype.js')
10
+ copy_file 'prototype_freeform.js', 'public/javascripts/freeform.js'
11
+ else
12
+ copy_file 'jquery_freeform.js', 'public/javascripts/freeform.js'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :freeform do
3
+ # # Task goes here
4
+ # end