reform 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0358800d71c3327b87d9d9659d789f67bd2195d
4
- data.tar.gz: bd6cba76f1f1b7a03b7a7d59599e7342b5bb9641
3
+ metadata.gz: e447e702b5effb25c8b881fb6c3056e57d39b5f9
4
+ data.tar.gz: 83ab3bdb3a48858fa273ea8985eb04bdee24e5d5
5
5
  SHA512:
6
- metadata.gz: 0df0530d354cca49618404e00466349af4c91b80021e7af1d69d2fb6302fd49a31727a4264d6628c3cb5c1f22b9f4c43a43e6da42ac1f2f8633659b14ff414c8
7
- data.tar.gz: 19c46cbabfbf81c5936417e209fdc4528f56a6847d9a541d542ca1fa00f7f0a5064653347dd759d6ffaab3a696d8037e40a007bdec332d97134f22339784f1d1
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
- nested_model = send(attr.getter) # decorated.hit # TODO: use bin.get
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
- Forms.new(nested_model.collect { |mdl| form_class.new(mdl)})
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
- inject(true) do |res, form|
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
 
@@ -78,7 +78,7 @@ module Reform::Form::ActiveModel
78
78
  if model_options
79
79
  form_name = model_options.first.to_s.camelize
80
80
  else
81
- form_name = name.sub(/Form$/, "")
81
+ form_name = name.sub(/(::)?Form$/, "") # Song::Form => "Song"
82
82
  end
83
83
 
84
84
  active_model_name_for(form_name)
@@ -1,3 +1,3 @@
1
1
  module Reform
2
- VERSION = "0.2.6"
2
+ VERSION = "0.2.7"
3
3
  end
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", ">= 1.7.5"
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"
@@ -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" }
@@ -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.6
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-03-15 00:00:00.000000000 Z
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.0.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,