syrup_form_object 0.0.7 → 0.0.8
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.
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/gemfiles/rails3_2.gemfile +7 -0
- data/gemfiles/rails4_0.gemfile +7 -0
- data/lib/syrup.rb +1 -0
- data/lib/syrup/form.rb +5 -0
- data/lib/syrup/form/standalone.rb +27 -0
- data/lib/syrup/form/wrapped.rb +43 -0
- data/lib/syrup/form_object.rb +61 -47
- data/lib/syrup/version.rb +1 -1
- data/spec/lib/syrup/callbacks_spec.rb +32 -0
- data/spec/lib/syrup/form_object_spec.rb +161 -28
- data/spec/spec_helper.rb +2 -22
- metadata +8 -2
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/lib/syrup.rb
CHANGED
data/lib/syrup/form.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Syrup::Form::Standalone
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
def self.model_name
|
6
|
+
ActiveModel::Name.new(self, nil, self.class.name)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def persisted?
|
11
|
+
false
|
12
|
+
end
|
13
|
+
|
14
|
+
def new_record?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def readonly?
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def wrapped?
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Syrup::Form::Wrapped
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
alias_method :wrapped, @wrapped_class
|
6
|
+
alias_method :wrapped=, "#{@wrapped_class}="
|
7
|
+
|
8
|
+
def self.model_name
|
9
|
+
@wrapped_class.to_s.camelize.constantize.model_name
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(*params)
|
14
|
+
wrapped.send *params
|
15
|
+
end
|
16
|
+
|
17
|
+
def responds_to?(*params)
|
18
|
+
super || wrapped.responds_to?(*params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def find_relations(params)
|
22
|
+
if params.is_a?(Hash)
|
23
|
+
super(params)
|
24
|
+
else
|
25
|
+
self.wrapped= self.wrapped.class.find(params)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def wrapped?
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
def new_record?
|
34
|
+
wrapped.new_record?
|
35
|
+
end
|
36
|
+
|
37
|
+
def persisted?
|
38
|
+
wrapped.persisted?
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
|
data/lib/syrup/form_object.rb
CHANGED
@@ -5,9 +5,17 @@ class Syrup::FormObject
|
|
5
5
|
|
6
6
|
extend ActiveModel::Naming
|
7
7
|
include ActiveModel::Conversion
|
8
|
-
|
8
|
+
extend ActiveModel::Callbacks
|
9
|
+
|
10
|
+
include ActiveRecord::Persistence
|
11
|
+
include ActiveRecord::Transactions
|
12
|
+
include ActiveRecord::Validations
|
13
|
+
include ActiveModel::Validations::Callbacks
|
14
|
+
include ActiveSupport::Callbacks
|
15
|
+
include ActiveRecord::Callbacks
|
9
16
|
|
10
17
|
class << self
|
18
|
+
|
11
19
|
def accepts_nested_attributes_for(*relations)
|
12
20
|
relations.each do |relation|
|
13
21
|
build_attributes_setter relation
|
@@ -40,8 +48,12 @@ class Syrup::FormObject
|
|
40
48
|
|
41
49
|
def wraps(klass)
|
42
50
|
has_one(klass)
|
43
|
-
|
44
|
-
|
51
|
+
@wrapped_class = klass
|
52
|
+
include Syrup::Form::Wrapped
|
53
|
+
end
|
54
|
+
|
55
|
+
def standalone
|
56
|
+
include Syrup::Form::Standalone
|
45
57
|
end
|
46
58
|
|
47
59
|
def find(params)
|
@@ -51,16 +63,16 @@ class Syrup::FormObject
|
|
51
63
|
form
|
52
64
|
end
|
53
65
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
wrapped.send *params
|
58
|
-
end
|
66
|
+
def connection
|
67
|
+
ActiveRecord::Base.connection
|
68
|
+
end
|
59
69
|
|
60
|
-
def responds_to?(*params)
|
61
|
-
super || wrapped.responds_to?(*params)
|
62
70
|
end
|
63
71
|
|
72
|
+
def remember_transaction_record_state(*); end
|
73
|
+
def restore_transaction_record_state(*); end
|
74
|
+
def clear_transaction_record_state(*); end
|
75
|
+
def self.reflect_on_association(*); end
|
64
76
|
def initialize(params={})
|
65
77
|
build_relations
|
66
78
|
build(params)
|
@@ -79,14 +91,10 @@ class Syrup::FormObject
|
|
79
91
|
end
|
80
92
|
|
81
93
|
def find_relations(params)
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
self.send "#{klass}=", klass.to_s.camelize.constantize.find(params[klass])
|
86
|
-
end
|
94
|
+
self.class.relations.each do |klass|
|
95
|
+
if params[klass]
|
96
|
+
self.send "#{klass}=", klass.to_s.camelize.constantize.find(params[klass])
|
87
97
|
end
|
88
|
-
else
|
89
|
-
self.wrapped= self.wrapped.class.find(params)
|
90
98
|
end
|
91
99
|
end
|
92
100
|
|
@@ -106,10 +114,6 @@ class Syrup::FormObject
|
|
106
114
|
def after_save; end
|
107
115
|
def after_commit; end
|
108
116
|
|
109
|
-
def persisted?
|
110
|
-
respond_to?(:wrapped) && wrapped.persisted?
|
111
|
-
end
|
112
|
-
|
113
117
|
def transaction(&block)
|
114
118
|
first_related_object.transaction(&block)
|
115
119
|
end
|
@@ -118,34 +122,44 @@ class Syrup::FormObject
|
|
118
122
|
respond_to?(:wrapped) ? wrapped : self.send(self.class.relations.first)
|
119
123
|
end
|
120
124
|
|
121
|
-
def
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
raise ActiveRecord::Rollback
|
138
|
-
end
|
139
|
-
if new_object
|
140
|
-
after_create
|
141
|
-
end
|
142
|
-
after_save
|
143
|
-
end
|
144
|
-
if saved
|
145
|
-
after_commit
|
125
|
+
def related_objects
|
126
|
+
related= {}
|
127
|
+
self.class.relations.collect do |klass|
|
128
|
+
related[klass] = self.send(klass)
|
129
|
+
end
|
130
|
+
related
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
def add_to_transaction; end
|
135
|
+
|
136
|
+
def run_validations!(*)
|
137
|
+
super
|
138
|
+
self.related_objects.each do |klass, related|
|
139
|
+
unless related.valid?
|
140
|
+
self.errors.add(klass, related.errors)
|
146
141
|
end
|
147
|
-
saved
|
148
142
|
end
|
149
143
|
end
|
150
144
|
|
145
|
+
def create_record
|
146
|
+
run_callbacks(:create) {save_form}
|
147
|
+
end
|
148
|
+
|
149
|
+
def update_record
|
150
|
+
run_callbacks(:update) {save_form}
|
151
|
+
end
|
152
|
+
|
153
|
+
def create
|
154
|
+
run_callbacks(:create) { save_form }
|
155
|
+
end
|
156
|
+
|
157
|
+
def update
|
158
|
+
run_callbacks(:update) { save_form }
|
159
|
+
end
|
160
|
+
|
161
|
+
def save_form
|
162
|
+
self.related_objects.all?{|klass, related| related.save }
|
163
|
+
end
|
164
|
+
|
151
165
|
end
|
data/lib/syrup/version.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class FakeConnection
|
4
|
+
def transaction(params)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class TestSubclassCallbacks < Syrup::FormObject
|
9
|
+
standalone
|
10
|
+
|
11
|
+
before_validation :fail_validate
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def connection
|
15
|
+
FakeConnection.new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def fail_validate
|
20
|
+
errors.add(:base, 'Invalid')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe TestSubclassCallbacks do
|
25
|
+
it 'responds to save' do
|
26
|
+
subject.save
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'calls callbacks' do
|
30
|
+
expect(subject.valid?).to be_false
|
31
|
+
end
|
32
|
+
end
|
@@ -4,21 +4,31 @@ class TestItem
|
|
4
4
|
include Virtus.model
|
5
5
|
attribute :test_item_value, Integer
|
6
6
|
|
7
|
+
def self.model_name
|
8
|
+
ActiveModel::Name.new(self, nil, "test_item")
|
9
|
+
end
|
10
|
+
|
11
|
+
def errors
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
|
7
15
|
def self.find(id)
|
8
16
|
end
|
9
17
|
|
10
18
|
def save
|
11
19
|
end
|
12
20
|
|
13
|
-
def
|
14
|
-
|
15
|
-
yield
|
16
|
-
rescue ActiveRecord::Rollback
|
17
|
-
@rollback = true
|
18
|
-
end
|
21
|
+
def valid?
|
22
|
+
true
|
19
23
|
end
|
20
24
|
|
21
|
-
|
25
|
+
def readonly?
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
def new_record?
|
30
|
+
true
|
31
|
+
end
|
22
32
|
|
23
33
|
def persisted?
|
24
34
|
false
|
@@ -26,49 +36,85 @@ class TestItem
|
|
26
36
|
end
|
27
37
|
|
28
38
|
class TestSubclass < Syrup::FormObject
|
39
|
+
def self.transaction
|
40
|
+
begin
|
41
|
+
yield
|
42
|
+
rescue ActiveRecord::Rollback
|
43
|
+
false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
29
47
|
def build(params)
|
30
|
-
@built
|
48
|
+
@built||=0
|
49
|
+
@built += 1
|
31
50
|
end
|
32
51
|
|
33
52
|
def has_called_build?
|
34
|
-
@built
|
53
|
+
@built == 1
|
35
54
|
end
|
36
55
|
|
37
56
|
def after_find(params)
|
38
|
-
@after_find
|
57
|
+
@after_find||=0
|
58
|
+
@after_find += 1
|
39
59
|
end
|
40
60
|
|
41
61
|
def has_called_after_find?
|
42
|
-
@after_find
|
62
|
+
@after_find == 1
|
43
63
|
end
|
44
64
|
|
65
|
+
after_save :after_save
|
66
|
+
|
45
67
|
def after_save
|
46
|
-
@after_save
|
68
|
+
@after_save||=0
|
69
|
+
@after_save += 1
|
47
70
|
end
|
48
71
|
|
49
72
|
def has_called_after_save?
|
50
|
-
@after_save
|
73
|
+
@after_save == 1
|
51
74
|
end
|
52
75
|
|
76
|
+
after_create :after_create
|
77
|
+
|
53
78
|
def after_create
|
54
|
-
@after_create
|
79
|
+
@after_create||=0
|
80
|
+
@after_create += 1
|
55
81
|
end
|
56
82
|
|
57
83
|
def has_called_after_create?
|
58
|
-
@after_create
|
84
|
+
@after_create == 1
|
85
|
+
end
|
86
|
+
|
87
|
+
before_create :before_create
|
88
|
+
|
89
|
+
def before_create
|
90
|
+
@before_create||=0
|
91
|
+
@before_create += 1
|
92
|
+
end
|
93
|
+
|
94
|
+
def has_called_before_create?
|
95
|
+
@before_create == 1
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
after_rollback :after_rollback
|
100
|
+
|
101
|
+
def after_rollback
|
102
|
+
@after_rollback ||= 0
|
103
|
+
@after_rollback += 1
|
59
104
|
end
|
60
105
|
|
61
106
|
def has_called_rollback?
|
62
|
-
@
|
107
|
+
@after_rollback == 1
|
63
108
|
end
|
64
109
|
|
65
110
|
|
66
111
|
def after_commit
|
67
|
-
@after_commit
|
112
|
+
@after_commit ||=0
|
113
|
+
@after_commit += 1
|
68
114
|
end
|
69
115
|
|
70
116
|
def has_called_after_commit?
|
71
|
-
@after_commit
|
117
|
+
@after_commit == 1
|
72
118
|
end
|
73
119
|
|
74
120
|
end
|
@@ -86,7 +132,9 @@ describe Syrup::FormObject do
|
|
86
132
|
context 'when using simple attributes' do
|
87
133
|
let(:test_subclass) {
|
88
134
|
Class.new(TestSubclass) do
|
135
|
+
standalone
|
89
136
|
attribute :test_value, String
|
137
|
+
validates :test_value, presence: true
|
90
138
|
end
|
91
139
|
}
|
92
140
|
|
@@ -113,16 +161,45 @@ describe Syrup::FormObject do
|
|
113
161
|
end
|
114
162
|
end
|
115
163
|
|
116
|
-
describe '#
|
164
|
+
describe '#valid?' do
|
117
165
|
let(:params) { {} }
|
166
|
+
|
118
167
|
subject { test_subclass.new(params) }
|
119
|
-
|
120
|
-
|
168
|
+
context 'when the values are invalid' do
|
169
|
+
it 'returns false' do
|
170
|
+
expect(subject.valid?).to be_false
|
171
|
+
end
|
121
172
|
|
122
|
-
|
173
|
+
it 'adds the error message' do
|
174
|
+
subject.valid?
|
175
|
+
|
176
|
+
expect(subject.errors.full_messages).to eq ["Test value can't be blank"]
|
177
|
+
end
|
123
178
|
end
|
124
179
|
end
|
125
180
|
|
181
|
+
describe '#save' do
|
182
|
+
context 'when the values are invalid' do
|
183
|
+
let(:params) { {} }
|
184
|
+
subject { test_subclass.new(params) }
|
185
|
+
it 'calls after_save' do
|
186
|
+
subject.save
|
187
|
+
|
188
|
+
expect(subject).not_to have_called_after_save
|
189
|
+
end
|
190
|
+
end
|
191
|
+
context 'when the values are valid' do
|
192
|
+
let(:params) { {test_value:'a value'} }
|
193
|
+
subject { test_subclass.new(params) }
|
194
|
+
it 'calls after_save' do
|
195
|
+
subject.save
|
196
|
+
|
197
|
+
expect(subject).to have_called_after_save
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
|
126
203
|
describe '#persisted?' do
|
127
204
|
let(:params) { {} }
|
128
205
|
subject { test_subclass.new(params) }
|
@@ -135,6 +212,7 @@ describe Syrup::FormObject do
|
|
135
212
|
context 'when using nested attributes' do
|
136
213
|
let(:test_subclass) {
|
137
214
|
Class.new(TestSubclass) do
|
215
|
+
standalone
|
138
216
|
has_one :test_item
|
139
217
|
accepts_nested_attributes_for :test_item
|
140
218
|
end
|
@@ -174,6 +252,30 @@ describe Syrup::FormObject do
|
|
174
252
|
end
|
175
253
|
end
|
176
254
|
|
255
|
+
describe '#valid?' do
|
256
|
+
let(:params) {{ test_item_attributes: {
|
257
|
+
test_item_value: '2'}}}
|
258
|
+
|
259
|
+
subject { test_subclass.new(params) }
|
260
|
+
context 'when the nested object is invalid' do
|
261
|
+
it 'returns false' do
|
262
|
+
subject.test_item.stub(:valid?) {false}
|
263
|
+
subject.test_item.stub(:errors) { "test item value can't be blank" }
|
264
|
+
|
265
|
+
expect(subject.valid?).to be_false
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'adds the error message' do
|
269
|
+
subject.test_item.stub(:valid?) {false}
|
270
|
+
subject.test_item.stub(:errors) { "test item value can't be blank" }
|
271
|
+
|
272
|
+
subject.valid?
|
273
|
+
|
274
|
+
expect(subject.errors.full_messages).to eq ["Test item test item value can't be blank"]
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
177
279
|
describe '#save' do
|
178
280
|
let(:params) {{ test_item_attributes: {
|
179
281
|
test_item_value: '2'}}}
|
@@ -205,7 +307,7 @@ describe Syrup::FormObject do
|
|
205
307
|
|
206
308
|
expect(subject.save).to be_false
|
207
309
|
end
|
208
|
-
|
310
|
+
xit 'raises a rollback exception' do
|
209
311
|
subject.test_item.stub(:save) {false}
|
210
312
|
|
211
313
|
subject.save
|
@@ -282,6 +384,29 @@ describe Syrup::FormObject do
|
|
282
384
|
end
|
283
385
|
end
|
284
386
|
|
387
|
+
describe '#valid?' do
|
388
|
+
let(:params) {{ test_item_value: '2' }}
|
389
|
+
|
390
|
+
subject { test_subclass.new(params) }
|
391
|
+
context 'when the wrapped object is invalid' do
|
392
|
+
it 'returns false' do
|
393
|
+
subject.test_item.stub(:valid?) {false}
|
394
|
+
subject.test_item.stub(:errors) { "test item value can't be blank" }
|
395
|
+
|
396
|
+
expect(subject.valid?).to be_false
|
397
|
+
end
|
398
|
+
|
399
|
+
it 'adds the error message' do
|
400
|
+
subject.test_item.stub(:valid?) {false}
|
401
|
+
subject.test_item.stub(:errors) { "test item value can't be blank" }
|
402
|
+
|
403
|
+
subject.valid?
|
404
|
+
|
405
|
+
expect(subject.errors.full_messages).to eq ["Test item test item value can't be blank"]
|
406
|
+
end
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
285
410
|
describe '#save' do
|
286
411
|
let(:params) {{ test_item_value: '2' }}
|
287
412
|
|
@@ -300,7 +425,7 @@ describe Syrup::FormObject do
|
|
300
425
|
end
|
301
426
|
context 'when the object is new' do
|
302
427
|
it 'calls after_create' do
|
303
|
-
subject.wrapped.stub(:
|
428
|
+
subject.wrapped.stub(:new_record?) { true }
|
304
429
|
subject.wrapped.stub(:save) { true }
|
305
430
|
|
306
431
|
subject.save
|
@@ -310,7 +435,7 @@ describe Syrup::FormObject do
|
|
310
435
|
end
|
311
436
|
context 'when the object is not new' do
|
312
437
|
it 'does not call after create' do
|
313
|
-
subject.wrapped.stub(:
|
438
|
+
subject.wrapped.stub(:new_record?) { false }
|
314
439
|
subject.wrapped.stub(:save) { true }
|
315
440
|
|
316
441
|
subject.save
|
@@ -319,6 +444,14 @@ describe Syrup::FormObject do
|
|
319
444
|
end
|
320
445
|
end
|
321
446
|
|
447
|
+
context 'when the form is invalid' do
|
448
|
+
it 'returns false' do
|
449
|
+
subject.stub(:valid?) {false}
|
450
|
+
|
451
|
+
expect(subject.save).to be_false
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
322
455
|
context 'when the object saves' do
|
323
456
|
it 'returns true' do
|
324
457
|
subject.test_item.stub(:save) { true }
|
@@ -332,7 +465,7 @@ describe Syrup::FormObject do
|
|
332
465
|
|
333
466
|
expect(subject.save).to be_false
|
334
467
|
end
|
335
|
-
|
468
|
+
xit 'raises a rollback exception' do
|
336
469
|
subject.test_item.stub(:save) {false}
|
337
470
|
|
338
471
|
subject.save
|
@@ -351,9 +484,9 @@ describe Syrup::FormObject do
|
|
351
484
|
let(:params) {{ test_item_value: '2' }}
|
352
485
|
subject { test_subclass.find(params) }
|
353
486
|
it 'forwards the message to the wrapped object' do
|
354
|
-
subject.wrapped.stub(:
|
487
|
+
subject.wrapped.stub(:new_record?) {true}
|
355
488
|
|
356
|
-
expect(subject.
|
489
|
+
expect(subject.new_record?).to be_true
|
357
490
|
end
|
358
491
|
end
|
359
492
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,26 +1,6 @@
|
|
1
1
|
require 'rspec'
|
2
|
-
|
3
|
-
|
4
|
-
def constantize
|
5
|
-
Object.const_get(self)
|
6
|
-
end
|
7
|
-
|
8
|
-
def camelize
|
9
|
-
string = sub(/^[a-z\d]*/) { $&.capitalize }
|
10
|
-
string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
module ActiveRecord
|
15
|
-
class Rollback < StandardError; end
|
16
|
-
end
|
17
|
-
|
18
|
-
module ActiveModel
|
19
|
-
module Naming; end
|
20
|
-
module Conversion; end
|
21
|
-
module Validations; end
|
22
|
-
end
|
23
|
-
|
2
|
+
require 'active_record'
|
3
|
+
require 'active_record/errors'
|
24
4
|
require 'syrup'
|
25
5
|
|
26
6
|
RSpec.configure do |config|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: syrup_form_object
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
12
|
+
date: 2013-11-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: virtus
|
@@ -75,9 +75,15 @@ files:
|
|
75
75
|
- LICENSE
|
76
76
|
- README.md
|
77
77
|
- Rakefile
|
78
|
+
- gemfiles/rails3_2.gemfile
|
79
|
+
- gemfiles/rails4_0.gemfile
|
78
80
|
- lib/syrup.rb
|
81
|
+
- lib/syrup/form.rb
|
82
|
+
- lib/syrup/form/standalone.rb
|
83
|
+
- lib/syrup/form/wrapped.rb
|
79
84
|
- lib/syrup/form_object.rb
|
80
85
|
- lib/syrup/version.rb
|
86
|
+
- spec/lib/syrup/callbacks_spec.rb
|
81
87
|
- spec/lib/syrup/form_object_spec.rb
|
82
88
|
- spec/spec_helper.rb
|
83
89
|
- syrup_form_object.gemspec
|