reform 0.2.6 → 0.2.7
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.
- checksums.yaml +4 -4
- data/CHANGES.md +6 -0
- data/README.md +8 -0
- data/database.sqlite3 +0 -0
- data/lib/reform/form.rb +30 -5
- data/lib/reform/form/active_model.rb +1 -1
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +1 -1
- data/test/active_model_test.rb +12 -2
- data/test/nested_form_test.rb +41 -1
- metadata +25 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e447e702b5effb25c8b881fb6c3056e57d39b5f9
|
4
|
+
data.tar.gz: 83ab3bdb3a48858fa273ea8985eb04bdee24e5d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6891ad8debef392f1ac60f79c962bb42004325b15aa0d5ef460c1456ec03152c12dacf0e933193f2b0630042af1bc4a86ea9f564ab69e2f2d369cc3517a9dea0
|
7
|
+
data.tar.gz: 4a4014071fb1f71da66d6124ba79f007d1e09bd2854ba6f989e299e931c158a5500408c171eb7f714704b930246d3ff5df46cd00a9d87d00ec49ef501d4201c9
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 0.2.7
|
2
|
+
|
3
|
+
* Last release supporting Representable 1.7.
|
4
|
+
* In ActiveModel/ActiveRecord: The model name is now correctly infered even if the name is something like `Song::Form`.
|
5
|
+
|
1
6
|
## 0.2.6
|
2
7
|
|
3
8
|
* Maintenance release cause I'm stupid.
|
@@ -6,6 +11,7 @@
|
|
6
11
|
|
7
12
|
* Allow proper form inheritance. When having `HitForm < SongForm < Reform::Form` the `HitForm` class will contain `SongForm`'s properties in addition to its own fields.
|
8
13
|
* `::model` is now inherited properly.
|
14
|
+
* Allow instantiation of nested form with emtpy nested properties.
|
9
15
|
|
10
16
|
## 0.2.4
|
11
17
|
|
data/README.md
CHANGED
@@ -4,6 +4,10 @@ Decouple your models from forms. Reform gives you a form object with validations
|
|
4
4
|
|
5
5
|
Although reform can be used in any Ruby framework, it comes with [Rails support](#rails-integration), works with [simple_form and other form gems](#formbuilder-support), allows nesting forms to implement [has_one](#nesting-forms-1-1-relations) and [has_many](#nesting-forms-1-n-relations) relationships, can [compose a form](#compositions) from multiple objects and gives you [coercion](#coercion).
|
6
6
|
|
7
|
+
# Development Status
|
8
|
+
|
9
|
+
Dear Reform users - you know I love all of you. Reform is currently being improved by myself. I am definitely *not* resisting all of the feature requests (especially about nesting, model validations, automatic model setup when validating has_many, etc.) but working hard to make it better. Expect a new Reform version _and_ better README mid-late April and please refrain from telling me how lazy I am. Thanks and see you soon!!! :heart:
|
10
|
+
|
7
11
|
|
8
12
|
## Installation
|
9
13
|
|
@@ -77,6 +81,10 @@ class SongsController
|
|
77
81
|
|
78
82
|
Reform uses the validations you provided in the form - and nothing else.
|
79
83
|
|
84
|
+
Note that Reform only updates values of the internal form attributes - the underlying model is still treated as immutuable and *remains unchanged*.
|
85
|
+
|
86
|
+
This allows rendering the form after `validate` with the data that has been submitted. However, don't get confused, the model's values are still the old, original values and are only changed after a `#save` or `#sync` operation.
|
87
|
+
|
80
88
|
|
81
89
|
## Saving Forms
|
82
90
|
|
data/database.sqlite3
CHANGED
Binary file
|
data/lib/reform/form.rb
CHANGED
@@ -76,6 +76,7 @@ module Reform
|
|
76
76
|
res = valid? # this validates on <Fields> using AM::Validations, currently.
|
77
77
|
#inject(true) do |res, form| # FIXME: replace that!
|
78
78
|
mapper.new(@fields).nested_forms do |attr, form| #.collect { |attr, form| nested[attr.from] = form }
|
79
|
+
next unless form # FIXME: this happens when the model's reader returns nil (property :song => nil). this shouldn't be considered by nested_forms!
|
79
80
|
res = validate_for(form, res, attr.from)
|
80
81
|
end
|
81
82
|
|
@@ -119,6 +120,7 @@ module Reform
|
|
119
120
|
|
120
121
|
def errors
|
121
122
|
@errors ||= Errors.new(self)
|
123
|
+
@errors
|
122
124
|
end
|
123
125
|
|
124
126
|
attr_accessor :model
|
@@ -173,11 +175,14 @@ module Reform
|
|
173
175
|
|
174
176
|
attr.options.merge!(
|
175
177
|
:getter => lambda do |*|
|
176
|
-
|
178
|
+
# FIXME: this is where i have to fix stuff.
|
179
|
+
nested_model = send(attr.getter) # or next # decorated.hit # TODO: use bin.get # DISCUSS: next moves on if property empty. this should be handled with representable's built-in mechanics.
|
177
180
|
|
178
181
|
if attr.options[:form_collection]
|
179
|
-
|
182
|
+
nested_model ||= []
|
183
|
+
Forms.new(nested_model.collect { |mdl| form_class.new(mdl)}, attr.options)
|
180
184
|
else
|
185
|
+
next unless nested_model # DISCUSS: do we want that?
|
181
186
|
form_class.new(nested_model)
|
182
187
|
end
|
183
188
|
end,
|
@@ -264,12 +269,16 @@ module Reform
|
|
264
269
|
require "representable/hash/collection"
|
265
270
|
require 'active_model'
|
266
271
|
class Forms < Array # DISCUSS: this should be a Form subclass.
|
272
|
+
def initialize(ary, options)
|
273
|
+
super(ary)
|
274
|
+
@options = options
|
275
|
+
end
|
276
|
+
|
267
277
|
include Form::ValidateMethods
|
268
278
|
|
279
|
+
# TODO: make valid?(errors) the only public method.
|
269
280
|
def valid?
|
270
|
-
|
271
|
-
res = validate_for(form, res)
|
272
|
-
end
|
281
|
+
res= validate_cardinality & validate_items
|
273
282
|
end
|
274
283
|
|
275
284
|
def errors
|
@@ -279,6 +288,22 @@ module Reform
|
|
279
288
|
# this gives us each { to_hash }
|
280
289
|
include Representable::Hash::Collection
|
281
290
|
items :parse_strategy => :sync, :instance => true
|
291
|
+
|
292
|
+
private
|
293
|
+
def validate_items
|
294
|
+
inject(true) do |res, form|
|
295
|
+
res = validate_for(form, res)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
def validate_cardinality
|
300
|
+
return true unless @options[:cardinality]
|
301
|
+
# TODO: use AM's cardinality validator here.
|
302
|
+
res = size >= @options[:cardinality][:minimum].to_i
|
303
|
+
|
304
|
+
errors.add(:size, "#{@options[:as]} size is 0 but must be #{@options[:cardinality].inspect}") unless res
|
305
|
+
res
|
306
|
+
end
|
282
307
|
end
|
283
308
|
end
|
284
309
|
|
data/lib/reform/version.rb
CHANGED
data/reform.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "representable", "
|
21
|
+
spec.add_dependency "representable", "~> 1.7.5"
|
22
22
|
spec.add_dependency "uber", "~> 0.0.4"
|
23
23
|
spec.add_dependency "activemodel"
|
24
24
|
spec.add_development_dependency "bundler", "~> 1.3"
|
data/test/active_model_test.rb
CHANGED
@@ -30,7 +30,7 @@ class NewActiveModelTest < MiniTest::Spec # TODO: move to test/rails/
|
|
30
30
|
|
31
31
|
it { class_with_model.model_name.must_be_kind_of ActiveModel::Name }
|
32
32
|
it { class_with_model.model_name.to_s.must_equal "Album" }
|
33
|
-
|
33
|
+
|
34
34
|
|
35
35
|
let (:subclass_of_class_with_model) {
|
36
36
|
Class.new(class_with_model)
|
@@ -40,6 +40,16 @@ class NewActiveModelTest < MiniTest::Spec # TODO: move to test/rails/
|
|
40
40
|
it { subclass_of_class_with_model.model_name.to_s.must_equal 'Album' }
|
41
41
|
|
42
42
|
|
43
|
+
describe "class named Song::Form" do
|
44
|
+
it do
|
45
|
+
class Form < Reform::Form
|
46
|
+
include Reform::Form::ActiveModel
|
47
|
+
self
|
48
|
+
end.model_name.to_s.must_equal "NewActiveModelTest"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
43
53
|
describe "inline with model" do
|
44
54
|
let (:form_class) {
|
45
55
|
Class.new(Reform::Form) do
|
@@ -52,7 +62,7 @@ class NewActiveModelTest < MiniTest::Spec # TODO: move to test/rails/
|
|
52
62
|
end
|
53
63
|
}
|
54
64
|
|
55
|
-
let (:inline) { form_class.new(OpenStruct.new).song }
|
65
|
+
let (:inline) { form_class.new(OpenStruct.new(:song => Object.new)).song }
|
56
66
|
|
57
67
|
it { inline.class.model_name.must_be_kind_of ActiveModel::Name }
|
58
68
|
it { inline.class.model_name.to_s.must_equal "Hit" }
|
data/test/nested_form_test.rb
CHANGED
@@ -41,11 +41,51 @@ class NestedFormTest < MiniTest::Spec
|
|
41
41
|
form.to_hash.must_equal({"hit"=>{"title"=>"Downtown"}, "title" => "Blackhawks Over Los Angeles", "songs"=>[{"title"=>"Calling"}]})
|
42
42
|
end
|
43
43
|
|
44
|
+
|
44
45
|
it "creates nested forms" do
|
45
46
|
form.hit.must_be_kind_of Reform::Form
|
46
47
|
form.songs.must_be_kind_of Reform::Form::Forms
|
47
48
|
end
|
48
49
|
|
50
|
+
describe "#initialize" do
|
51
|
+
describe "with empty object and no cardinality" do
|
52
|
+
let(:form) { AlbumForm.new(OpenStruct.new) }
|
53
|
+
|
54
|
+
it "allows initialization with empty properties" do
|
55
|
+
form
|
56
|
+
end
|
57
|
+
|
58
|
+
it "allows #validate" do
|
59
|
+
form.validate({})
|
60
|
+
form.errors.messages.must_equal(:title=>["can't be blank"])
|
61
|
+
end
|
62
|
+
# it "must support #validate when initialized with empty properties" do
|
63
|
+
# form.validate({})
|
64
|
+
# form.errors.messages.must_equal(:title=>["can't be blank"], :"hit.title"=>["can't be blank"], :"songs.title"=>["can't be blank"])
|
65
|
+
# end
|
66
|
+
# it "must support #validate with attributes when initialized with empty properties" do
|
67
|
+
# form.validate("hit"=>{"title"=>"Downtown"}, "title" => "Blackhawks Over Los Angeles", "songs"=>[{"title"=>"Calling"}])
|
68
|
+
# form.title.must_eql "Blackhawks Over Los Angeles"
|
69
|
+
# form.errors.messages.must_equal([])
|
70
|
+
# end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "with empty object and cardinality" do
|
74
|
+
subject { Class.new(Reform::Form) do
|
75
|
+
# collection :songs, :validates => {:length => {:minimum => 1}}
|
76
|
+
collection :songs, :cardinality => {:minimum => 1} do
|
77
|
+
property :title
|
78
|
+
end
|
79
|
+
end.new(OpenStruct.new) }
|
80
|
+
|
81
|
+
it "whatxxx" do
|
82
|
+
subject.validate({}).must_equal false
|
83
|
+
subject.errors.messages.must_equal(:"songs.size"=>["songs size is 0 but must be {:minimum=>1}"])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
|
49
89
|
describe "rendering" do
|
50
90
|
it { form.title.must_equal "Blackhawks Over Los Angeles" }
|
51
91
|
it { form.hit.title.must_equal "Downtown" }
|
@@ -171,4 +211,4 @@ class NestedFormTest < MiniTest::Spec
|
|
171
211
|
end
|
172
212
|
end
|
173
213
|
end
|
174
|
-
end
|
214
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reform
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
@@ -9,76 +9,76 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-04-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: representable
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: 1.7.5
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 1.7.5
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: uber
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- - ~>
|
32
|
+
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: 0.0.4
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- - ~>
|
39
|
+
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: 0.0.4
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: activemodel
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- -
|
46
|
+
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: '0'
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- -
|
53
|
+
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '0'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: bundler
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- - ~>
|
60
|
+
- - "~>"
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: '1.3'
|
63
63
|
type: :development
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- - ~>
|
67
|
+
- - "~>"
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '1.3'
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: rake
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- -
|
74
|
+
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: 10.1.0
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- -
|
81
|
+
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: 10.1.0
|
84
84
|
- !ruby/object:Gem::Dependency
|
@@ -99,56 +99,56 @@ dependencies:
|
|
99
99
|
name: activerecord
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- -
|
102
|
+
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
104
|
version: '0'
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- -
|
109
|
+
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '0'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: sqlite3
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
|
-
- -
|
116
|
+
- - ">="
|
117
117
|
- !ruby/object:Gem::Version
|
118
118
|
version: '0'
|
119
119
|
type: :development
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- -
|
123
|
+
- - ">="
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: virtus
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
|
-
- -
|
130
|
+
- - ">="
|
131
131
|
- !ruby/object:Gem::Version
|
132
132
|
version: '0'
|
133
133
|
type: :development
|
134
134
|
prerelease: false
|
135
135
|
version_requirements: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
|
-
- -
|
137
|
+
- - ">="
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '0'
|
140
140
|
- !ruby/object:Gem::Dependency
|
141
141
|
name: rails
|
142
142
|
requirement: !ruby/object:Gem::Requirement
|
143
143
|
requirements:
|
144
|
-
- -
|
144
|
+
- - ">="
|
145
145
|
- !ruby/object:Gem::Version
|
146
146
|
version: '0'
|
147
147
|
type: :development
|
148
148
|
prerelease: false
|
149
149
|
version_requirements: !ruby/object:Gem::Requirement
|
150
150
|
requirements:
|
151
|
-
- -
|
151
|
+
- - ">="
|
152
152
|
- !ruby/object:Gem::Version
|
153
153
|
version: '0'
|
154
154
|
description: Freeing your AR models from form logic.
|
@@ -159,8 +159,8 @@ executables: []
|
|
159
159
|
extensions: []
|
160
160
|
extra_rdoc_files: []
|
161
161
|
files:
|
162
|
-
- .gitignore
|
163
|
-
- .travis.yml
|
162
|
+
- ".gitignore"
|
163
|
+
- ".travis.yml"
|
164
164
|
- CHANGES.md
|
165
165
|
- Gemfile
|
166
166
|
- LICENSE.txt
|
@@ -229,17 +229,17 @@ require_paths:
|
|
229
229
|
- lib
|
230
230
|
required_ruby_version: !ruby/object:Gem::Requirement
|
231
231
|
requirements:
|
232
|
-
- -
|
232
|
+
- - ">="
|
233
233
|
- !ruby/object:Gem::Version
|
234
234
|
version: '0'
|
235
235
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
236
236
|
requirements:
|
237
|
-
- -
|
237
|
+
- - ">="
|
238
238
|
- !ruby/object:Gem::Version
|
239
239
|
version: '0'
|
240
240
|
requirements: []
|
241
241
|
rubyforge_project:
|
242
|
-
rubygems_version: 2.
|
242
|
+
rubygems_version: 2.2.1
|
243
243
|
signing_key:
|
244
244
|
specification_version: 4
|
245
245
|
summary: Decouples your models from form by giving you form objects with validation,
|