freeform 0.0.3.rc1 → 0.0.3.rc2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -12,7 +12,7 @@ FreeForm is designed primarily with Rails in mind, but it should work on any Rub
12
12
 
13
13
  Add this line to your application's Gemfile:
14
14
 
15
- gem 'freeform'
15
+ gem 'freeform', '~> 0.0.3rc2'
16
16
 
17
17
  And then execute:
18
18
 
@@ -212,16 +212,28 @@ form.build_phone_numbers(:phone => Phone.new)
212
212
  form.build_phone_number(:phone => Phone.new)
213
213
  ```
214
214
 
215
- You can specify the default initializers for that form with the accessor `#{nested_form_name}_form_initializer`.
215
+ **Working with nested_form gem**
216
+ In order to support the `nested_form` gem, FreeForm currently uses a bit of hackiness. You actually need to specify an option on your nested forms called `class_initializer`, that points to a class method to use to specify the default parameters. You can either provide the method hardcoded into the class, or set it externally. It accepts either a hardcoded hash, or a Proc.
216
217
  ```ruby
217
- form = UserForm.new(
218
- :user => User.new,
219
- :phone_numbers_form_initializer => {:phone => Phone.new} )
218
+ class UserForm < FreeForm::Form
219
+ form_models :user
220
220
 
221
- form.build_phone_numbers
222
- form.build_phone_number
221
+ property :username, :on => :user
222
+ property :email, :on => :user
223
+
224
+ nested_form :phone_numbers, :class_initializer => :phone_initializer do
225
+ form_models :phone
226
+
227
+ property :area_code, :on => :phone
228
+ property :number, :on => :phone
229
+ end
230
+ end
231
+
232
+ UserForm.phone_initializer = lambda { { :phone => Phone.new } }
233
+ form = UserForm.new( :user => User.new )
234
+ form.build_phone_number # Uses Phone.new to initialize the nested form.
223
235
  ```
224
- This is a necessary parameter if you're using the `nested_form` gem, as new nested forms are initialized automatically.
236
+ I apologize for the ugliness - In the future, I plan to roll FreeForm's own version of the `nested_form` javascript functionality.
225
237
 
226
238
  ## Initialize With Care!
227
239
 
@@ -238,7 +250,7 @@ class UserForm < FreeForm::Form
238
250
  property :username, :on => :user
239
251
  property :email, :on => :user
240
252
 
241
- nested_form :phone_numbers do
253
+ nested_form :phone_numbers, :class_initializer => :phone_initializer do
242
254
  form_models :phone
243
255
 
244
256
  property :area_code, :on => :phone
@@ -253,6 +265,7 @@ Will the current_user's phone numbers automatically appear as nested forms? **No
253
265
  If you want them there, put them there, like this:
254
266
 
255
267
  ```ruby
268
+ UserForm.phone_initializer = lambda { { :phone => current_user.phone_numbers.build } }
256
269
  current_user.phone_numbers.each do |phone_number|
257
270
  form.build_phone_number(:phone => phone_number)
258
271
  end
@@ -12,6 +12,21 @@ module FreeForm
12
12
  attr_accessor :nested_forms
13
13
 
14
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
29
+
15
30
  # Define an attr_accessor for the parent class to hold this attribute
16
31
  declared_model(attribute)
17
32
 
@@ -19,6 +34,22 @@ module FreeForm
19
34
  nested_form_class = Class.new(FreeForm::Form) do
20
35
  include FreeForm::Property
21
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
22
53
  end
23
54
  self.const_set("#{attribute.to_s.camelize}Form", nested_form_class)
24
55
 
@@ -53,18 +84,10 @@ module FreeForm
53
84
  @nested_attributes ||= []
54
85
  end
55
86
 
56
- # Example: form.address_form_initializer (aliased to form.addresses_form_initializer)
57
- attr_accessor :"#{attribute}_form_initializer"
58
- alias_method :"#{singularized_attribute}_form_initializer", :"#{attribute}_form_initializer"
59
- alias_method :"#{singularized_attribute}_form_initializer=", :"#{attribute}_form_initializer="
60
-
61
87
  # Example: form.build_addresses (optional custom initializer)
62
- define_method(:"build_#{attribute}") do |initializer=nil|
88
+ define_method(:"build_#{attribute}") do |initializer={}|
63
89
  # Get correct class
64
90
  form_class = self.class.nested_forms[:"#{attribute}"]
65
-
66
- # Set default intializer if none provided
67
- initializer ||= send("#{attribute}_form_initializer").call
68
91
 
69
92
  # Build new model
70
93
  form_model = form_class.new(initializer)
@@ -93,4 +93,7 @@ module FreeForm
93
93
  end
94
94
  end
95
95
  end
96
+
97
+ #Instance Methods
98
+ #----------------------------------------------------------------------------
96
99
  end
@@ -1,3 +1,3 @@
1
1
  module Freeform
2
- VERSION = "0.0.3.rc1"
2
+ VERSION = "0.0.3.rc2"
3
3
  end
@@ -57,12 +57,12 @@ describe FreeForm::Form do
57
57
  allow_destroy_on_save
58
58
 
59
59
  property :username, :on => :user
60
- property :email, :on => :user
60
+ property :email, :on => :user
61
61
  property :street, :on => :address
62
62
  property :city, :on => :address
63
63
  property :state, :on => :address
64
64
 
65
- has_many :phone_numbers do
65
+ has_many :phone_numbers, :class_initializer => :phone_number_initializer do
66
66
  form_model :phone
67
67
  validate_models
68
68
  allow_destroy_on_save
@@ -79,11 +79,8 @@ describe FreeForm::Form do
79
79
  end
80
80
 
81
81
  let(:form) do
82
- form_model = form_class.new(
83
- :user => user_class.new,
84
- :address => address_class.new,
85
- :phone_numbers_form_initializer => lambda { { :phone => phone_class.new } }
86
- )
82
+ form_class.phone_number_initializer = lambda { {:phone => phone_class.new} }
83
+ form_model = form_class.new( :user => user_class.new, :address => address_class.new)
87
84
  form_model.build_phone_number
88
85
  form_model
89
86
  end
@@ -9,13 +9,13 @@ describe FreeForm::Nested do
9
9
  klass = Class.new(Module) do
10
10
  include FreeForm::Property
11
11
  include FreeForm::Nested
12
-
13
- has_many :mailing_addresses do
12
+
13
+ has_many :mailing_addresses, :class_initializer => :mailing_address_initializer do
14
14
  declared_model :address
15
15
 
16
- property :street, :on => :address
16
+ property :street, :on => :address
17
17
  end
18
-
18
+
19
19
  def initialize(h={})
20
20
  h.each {|k,v| send("#{k}=",v)}
21
21
  end
@@ -28,9 +28,8 @@ describe FreeForm::Nested do
28
28
  end
29
29
 
30
30
  let(:form) do
31
- form_model = form_class.new(
32
- :mailing_address_form_initializer => lambda { { :address => OpenStruct.new } }
33
- )
31
+ form_class.mailing_address_initializer = lambda { { :address => OpenStruct.new } }
32
+ form_model = form_class.new
34
33
  end
35
34
 
36
35
  describe "form class" do
@@ -53,7 +52,8 @@ describe FreeForm::Nested do
53
52
 
54
53
  it "builds unique models" do
55
54
  # Using module here, since they initialize uniquely
56
- form.mailing_address_form_initializer = lambda { { :address => Module.new } }
55
+ form_class.mailing_address_initializer = lambda { { :address => Module.new } }
56
+ form = form_class.new
57
57
  form.build_mailing_address
58
58
  form.build_mailing_address
59
59
  address_1 = form.mailing_addresses.first.address
@@ -61,6 +61,12 @@ describe FreeForm::Nested do
61
61
  address_1.should_not eq(address_2)
62
62
  end
63
63
 
64
+ it "builds initialized models through reflection on association" do
65
+ form_class.mailing_address_initializer = lambda { { :address => Module.new } }
66
+ klass = form_class.reflect_on_association(:mailing_addresses).klass
67
+ klass.new.address.should be_a(Module)
68
+ end
69
+
64
70
  it "allows nested_forms to be built with custom initializers" do
65
71
  form.build_mailing_address(:address => OpenStruct.new(:street => "1600 Pennsylvania Ave."))
66
72
  form.mailing_addresses.first.street.should eq("1600 Pennsylvania Ave.")
@@ -46,12 +46,16 @@ describe FreeForm::Validation do
46
46
  property :username, :on => :user
47
47
  validates :username, :presence => true
48
48
 
49
- nested_form :addresses do
49
+ nested_form :addresses, :class_initializer => :address_initializer do
50
50
  declared_model :address
51
51
 
52
52
  property :street, :on => :address
53
53
  end
54
54
 
55
+ def self.address_initializer
56
+ {:address => OpenStruct.new}
57
+ end
58
+
55
59
  def initialize(h={})
56
60
  h.each {|k,v| send("#{k}=",v)}
57
61
  end
@@ -64,10 +68,8 @@ describe FreeForm::Validation do
64
68
  end
65
69
 
66
70
  let(:form) do
67
- test_form = form_class.new(
68
- :user => user,
69
- :address_form_initializer => lambda { { :address => address } } )
70
- test_form.build_address
71
+ test_form = form_class.new(:user => user)
72
+ test_form.build_address(:address => address)
71
73
  test_form
72
74
  end
73
75
 
@@ -100,7 +102,7 @@ describe FreeForm::Validation do
100
102
  property :form_property
101
103
  validates :form_property, :presence => true
102
104
 
103
- nested_form :addresses do
105
+ nested_form :addresses, :class_initializer => :address_initializer do
104
106
  include ActiveModel::Validations
105
107
  include FreeForm::Property
106
108
  include FreeForm::Nested
@@ -112,6 +114,10 @@ describe FreeForm::Validation do
112
114
  property :city, :on => :address
113
115
  end
114
116
 
117
+ def self.address_initializer
118
+ {:address => OpenStruct.new}
119
+ end
120
+
115
121
  def initialize(h={})
116
122
  h.each {|k,v| send("#{k}=",v)}
117
123
  end
@@ -124,10 +130,8 @@ describe FreeForm::Validation do
124
130
  end
125
131
 
126
132
  let(:form) do
127
- test_form = form_class.new(
128
- :user => user,
129
- :address_form_initializer => lambda { { :address => address } } )
130
- test_form.build_address
133
+ test_form = form_class.new( :user => user )
134
+ test_form.build_address( :address => address )
131
135
  test_form
132
136
  end
133
137
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: freeform
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3.rc1
4
+ version: 0.0.3.rc2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors: