reform 2.0.0 → 2.0.1

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: 247ffc53838f5e69a71f4ab5d066572b05308003
4
- data.tar.gz: f6162c6a018e02ad2f9c487441dcea08623b960a
3
+ metadata.gz: 037b79d11746474c6c396824536f8bd567e59879
4
+ data.tar.gz: 4d448833f2cde88977600d0e9cc85686550eeda8
5
5
  SHA512:
6
- metadata.gz: 31ee6b2d4656b94ced0c7790832e8b6be84ea2b8218866c5cb9e75c6b3099710e9e2a52a24cd54b9c40ba0ead9a9712e7e961ac4b463f48bb34131b305c22246
7
- data.tar.gz: d8954f5806cdbbd701b4e8352d930f2b1bd3aef5a36d5621ef154a0132e6e46481137b5f1d9208932a0377805f81cac75ee066885cf73b2ea4778957e8c1192b
6
+ metadata.gz: a40d0cde85b16d5b4f4fbfa06cde1549e961044986abda2a95cb0abc2a22224a8b0b7dd88a7e80706b9b78b1932056d0091d4c858f7d3e67b523ced40bdd1285
7
+ data.tar.gz: bc964b5838dabcaac8b47db139a6a6b86c624b133297af97489d6dd1f465bb375cb47c9186c52832ad4ebea03227095f0947629edfc3678090fd471e2e06ff66
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 2.0.1
2
+
3
+ * Fix `ActiveModel::Validations` where translations in custom validations would error. This is now handled by delegating back to the `Valiator` object in Reform.
4
+
1
5
  ## 2.0.0
2
6
 
3
7
  * The `::reform_2_0!` is no longer there. Guess why.
data/README.md CHANGED
@@ -113,8 +113,12 @@ It's then up to you what to do with the updated models - they're still unsaved.
113
113
  The easiest way to save the data is to call `#save` on the form.
114
114
 
115
115
  ```ruby
116
- @form.save #=> populates album with incoming data
117
- # by calling @form.album.title=.
116
+ if @form.validate(params[:song])
117
+ @form.save #=> populates album with incoming data
118
+ # by calling @form.album.title=.
119
+ else
120
+ # handle validation errors.
121
+ end
118
122
  ```
119
123
 
120
124
  This will sync the data to the model and then call `album.save`.
Binary file
@@ -5,13 +5,16 @@ require "uber/delegates"
5
5
  module Reform::Form::ActiveModel
6
6
  # AM::Validations for your form.
7
7
  #
8
- # Note: The preferred way for validations should be Lotus::Validations, as ActiveModel::Validation's implementation is
9
- # old, very complex given that it needs to do a simple thing, and it's using globals like @errors.
8
+ # Note: The preferred way for validations should be Lotus::Validations, as ActiveModel::Validation's
9
+ # implementation is old, very complex given that it needs to do a simple thing, is using
10
+ # globals like @errors, and relies and more than 100 methods to be mixed into your form.
10
11
  #
11
12
  # Implements ::validates and friends, and #valid?.
13
+ #
12
14
  module Validations
13
15
  def self.included(includer)
14
16
  includer.instance_eval do
17
+ include Reform::Form::ActiveModel
15
18
  extend Uber::InheritableAttr
16
19
  inheritable_attr :validator
17
20
  self.validator = Class.new(Validator)
@@ -19,6 +22,9 @@ module Reform::Form::ActiveModel
19
22
  class << self
20
23
  extend Uber::Delegates
21
24
  delegates :validator, :validates, :validate, :validates_with, :validate_with
25
+
26
+ # Hooray! Delegate translation back to Reform's Validator class which contains AM::Validations.
27
+ delegates :validator, :human_attribute_name, :lookup_ancestors, :i18n_scope # Rails 3.1.
22
28
  end
23
29
  end
24
30
  end
@@ -27,6 +33,12 @@ module Reform::Form::ActiveModel
27
33
  Reform::Contract::Errors.new(self)
28
34
  end
29
35
 
36
+ # The concept of "composition" has still not arrived in Rails core and they rely on 400 methods being
37
+ # available in one object. This is why we need to provide parts of the I18N API in the form.
38
+ def read_attribute_for_validation(name)
39
+ send(name)
40
+ end
41
+
30
42
 
31
43
  # Validators is the validatable object. On the class level, we define validations,
32
44
  # on instance, it exposes #valid?.
@@ -44,9 +56,6 @@ module Reform::Form::ActiveModel
44
56
  @form.send(method_name, *args, &block)
45
57
  end
46
58
 
47
- # def self.model_name # FIXME: this is only needed for i18n, it seems.
48
- # "Reform::Form"
49
- # end
50
59
  def self.model_name
51
60
  ActiveModel::Name.new(Reform::Form)
52
61
  end
@@ -57,7 +66,8 @@ module Reform::Form::ActiveModel
57
66
  end
58
67
  end
59
68
 
60
-
69
+ # Needs to be implemented by every validation backend and implements the
70
+ # actual validation. See Reform::Form::Lotus, too!
61
71
  def valid?
62
72
  validator = self.class.validator.new(self)
63
73
  validator.valid? # run the Validations object's validator with the form as context. this won't pollute anything in the form.
@@ -1,4 +1,4 @@
1
1
  require 'reform/form/active_model'
2
2
  require 'reform/form/orm'
3
3
  require 'reform/form/mongoid'
4
- require 'reform/form/model_reflections' # only load this in AR context as simple_form currently is bound to AR.
4
+ require 'reform/form/active_model/model_reflections' # only load this in AR context as simple_form currently is bound to AR.
@@ -1,3 +1,3 @@
1
1
  module Reform
2
- VERSION = "2.0.0"
2
+ VERSION = "2.0.1"
3
3
  end
@@ -0,0 +1,47 @@
1
+ require 'test_helper'
2
+
3
+ class ActiveModelCustomValidationTranslationsTest < MiniTest::Spec
4
+ module SongForm
5
+ class WithBlock < Reform::Form
6
+ property :title
7
+
8
+ validate do
9
+ errors.add :title, :blank
10
+ end
11
+ end
12
+
13
+ class WithLambda < Reform::Form
14
+ property :title
15
+
16
+ validate ->{ errors.add :title, :blank }
17
+ end
18
+
19
+ class WithMethod < Reform::Form
20
+ property :title
21
+
22
+ validate :custom_validation_method
23
+ def custom_validation_method
24
+ errors.add :title, :blank
25
+ end
26
+ end
27
+ end
28
+
29
+
30
+ it 'translates the error message when custom validation is used with block' do
31
+ form = SongForm::WithBlock.new(Song.new)
32
+ form.validate({})
33
+ form.errors[:title].must_include "can't be blank"
34
+ end
35
+
36
+ it 'translates the error message when custom validation is used with lambda' do
37
+ form = SongForm::WithLambda.new(Song.new)
38
+ form.validate({})
39
+ form.errors[:title].must_include "can't be blank"
40
+ end
41
+
42
+ it 'translates the error message when custom validation is used with method' do
43
+ form = SongForm::WithMethod.new(Song.new)
44
+ form.validate({})
45
+ form.errors[:title].must_include "can't be blank"
46
+ end
47
+ end
@@ -1,5 +1,205 @@
1
- # Sample localization file for English. Add more files in this directory for other locales.
2
- # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
-
1
+ ---
4
2
  en:
5
- hello: "Hello world"
3
+ date:
4
+ abbr_day_names:
5
+ - Sun
6
+ - Mon
7
+ - Tue
8
+ - Wed
9
+ - Thu
10
+ - Fri
11
+ - Sat
12
+ abbr_month_names:
13
+ -
14
+ - Jan
15
+ - Feb
16
+ - Mar
17
+ - Apr
18
+ - May
19
+ - Jun
20
+ - Jul
21
+ - Aug
22
+ - Sep
23
+ - Oct
24
+ - Nov
25
+ - Dec
26
+ day_names:
27
+ - Sunday
28
+ - Monday
29
+ - Tuesday
30
+ - Wednesday
31
+ - Thursday
32
+ - Friday
33
+ - Saturday
34
+ formats:
35
+ default: "%Y-%m-%d"
36
+ long: "%B %d, %Y"
37
+ short: "%b %d"
38
+ month_names:
39
+ -
40
+ - January
41
+ - February
42
+ - March
43
+ - April
44
+ - May
45
+ - June
46
+ - July
47
+ - August
48
+ - September
49
+ - October
50
+ - November
51
+ - December
52
+ order:
53
+ - :year
54
+ - :month
55
+ - :day
56
+ datetime:
57
+ distance_in_words:
58
+ about_x_hours:
59
+ one: about 1 hour
60
+ other: about %{count} hours
61
+ about_x_months:
62
+ one: about 1 month
63
+ other: about %{count} months
64
+ about_x_years:
65
+ one: about 1 year
66
+ other: about %{count} years
67
+ almost_x_years:
68
+ one: almost 1 year
69
+ other: almost %{count} years
70
+ half_a_minute: half a minute
71
+ less_than_x_minutes:
72
+ one: less than a minute
73
+ other: less than %{count} minutes
74
+ less_than_x_seconds:
75
+ one: less than 1 second
76
+ other: less than %{count} seconds
77
+ over_x_years:
78
+ one: over 1 year
79
+ other: over %{count} years
80
+ x_days:
81
+ one: 1 day
82
+ other: "%{count} days"
83
+ x_minutes:
84
+ one: 1 minute
85
+ other: "%{count} minutes"
86
+ x_months:
87
+ one: 1 month
88
+ other: "%{count} months"
89
+ x_seconds:
90
+ one: 1 second
91
+ other: "%{count} seconds"
92
+ prompts:
93
+ day: Day
94
+ hour: Hour
95
+ minute: Minute
96
+ month: Month
97
+ second: Seconds
98
+ year: Year
99
+ errors:
100
+ format: "%{attribute} %{message}"
101
+ messages:
102
+ accepted: must be accepted
103
+ blank: can't be blank
104
+ present: must be blank
105
+ confirmation: doesn't match %{attribute}
106
+ empty: can't be empty
107
+ equal_to: must be equal to %{count}
108
+ even: must be even
109
+ exclusion: is reserved
110
+ greater_than: must be greater than %{count}
111
+ greater_than_or_equal_to: must be greater than or equal to %{count}
112
+ inclusion: is not included in the list
113
+ invalid: is invalid
114
+ less_than: must be less than %{count}
115
+ less_than_or_equal_to: must be less than or equal to %{count}
116
+ not_a_number: is not a number
117
+ not_an_integer: must be an integer
118
+ odd: must be odd
119
+ record_invalid: 'Validation failed: %{errors}'
120
+ restrict_dependent_destroy:
121
+ one: Cannot delete record because a dependent %{record} exists
122
+ many: Cannot delete record because dependent %{record} exist
123
+ taken: has already been taken
124
+ too_long:
125
+ one: is too long (maximum is 1 character)
126
+ other: is too long (maximum is %{count} characters)
127
+ too_short:
128
+ one: is too short (minimum is 1 character)
129
+ other: is too short (minimum is %{count} characters)
130
+ wrong_length:
131
+ one: is the wrong length (should be 1 character)
132
+ other: is the wrong length (should be %{count} characters)
133
+ other_than: must be other than %{count}
134
+ template:
135
+ body: 'There were problems with the following fields:'
136
+ header:
137
+ one: 1 error prohibited this %{model} from being saved
138
+ other: "%{count} errors prohibited this %{model} from being saved"
139
+ helpers:
140
+ select:
141
+ prompt: Please select
142
+ submit:
143
+ create: Create %{model}
144
+ submit: Save %{model}
145
+ update: Update %{model}
146
+ number:
147
+ currency:
148
+ format:
149
+ delimiter: ","
150
+ format: "%u%n"
151
+ precision: 2
152
+ separator: "."
153
+ significant: false
154
+ strip_insignificant_zeros: false
155
+ unit: "$"
156
+ format:
157
+ delimiter: ","
158
+ precision: 3
159
+ separator: "."
160
+ significant: false
161
+ strip_insignificant_zeros: false
162
+ human:
163
+ decimal_units:
164
+ format: "%n %u"
165
+ units:
166
+ billion: Billion
167
+ million: Million
168
+ quadrillion: Quadrillion
169
+ thousand: Thousand
170
+ trillion: Trillion
171
+ unit: ''
172
+ format:
173
+ delimiter: ''
174
+ precision: 3
175
+ significant: true
176
+ strip_insignificant_zeros: true
177
+ storage_units:
178
+ format: "%n %u"
179
+ units:
180
+ byte:
181
+ one: Byte
182
+ other: Bytes
183
+ gb: GB
184
+ kb: KB
185
+ mb: MB
186
+ tb: TB
187
+ percentage:
188
+ format:
189
+ delimiter: ''
190
+ format: "%n%"
191
+ precision:
192
+ format:
193
+ delimiter: ''
194
+ support:
195
+ array:
196
+ last_word_connector: ", and "
197
+ two_words_connector: " and "
198
+ words_connector: ", "
199
+ time:
200
+ am: am
201
+ formats:
202
+ default: "%a, %d %b %Y %H:%M:%S %z"
203
+ long: "%B %d, %Y %H:%M"
204
+ short: "%d %b %H:%M"
205
+ pm: pm
@@ -1,311 +1,313 @@
1
- # require 'test_helper'
2
- # def mongoid_present?
3
- # require 'mongoid'
4
- # Mongoid.configure do |config|
5
- # config.connect_to("reform-mongoid-test")
6
- # end
7
- # true
8
- # rescue
9
- # false
10
- # end
11
-
12
- # if mongoid_present?
13
- # require 'reform/mongoid'
14
-
15
- # class Disc
16
- # include Mongoid::Document
17
- # field :title, type: String
18
- # has_many :tunes
19
- # has_and_belongs_to_many :musicians
20
- # end
21
-
22
- # class Musician
23
- # include Mongoid::Document
24
- # field :name, type: String
25
- # end
26
-
27
- # class Tune
28
- # include Mongoid::Document
29
- # include Mongoid::Timestamps
30
- # field :title, type: String
31
- # belongs_to :disc
32
- # belongs_to :musician
33
- # end
34
-
35
- # class MongoidTest < MiniTest::Spec
36
- # class TuneForm < Reform::Form
37
- # include Reform::Form::Mongoid
38
- # model :tune
39
-
40
- # property :title
41
- # property :created_at
42
-
43
- # validates_uniqueness_of :title, scope: [:disc_id, :musician_id]
44
- # validates :created_at, :presence => true # have another property to test if we mix up.
45
-
46
- # property :musician do
47
- # property :name
48
- # validates_uniqueness_of :name # this currently also tests if Form::AR is included as a feature.
49
- # end
50
- # end
51
-
52
- # let(:disc) { Disc.create(:title => "Damnation") }
53
- # let(:musician) { Musician.create(:name => "Opeth") }
54
- # let(:form) { TuneForm.new(Tune.new(:musician => Musician.new)) }
55
-
56
- # it { form.class.i18n_scope.must_equal :mongoid }
57
-
58
- # it "allows accessing the database" do
59
- # end
60
-
61
- # # uniqueness
62
- # it "has no errors on title when title is unique for the same musician and disc" do
63
- # form.validate("title" => "The Gargoyle", "musician_id" => musician.id, "disc" => disc.id, "created_at" => "November 6, 1966")
64
- # assert_empty form.errors[:title]
65
- # end
66
-
67
- # it "has errors on title when title is taken for the same musician and disc" do
68
- # skip "replace ActiveModel::Validations with our own, working and reusable gem."
69
- # Tune.create(title: "Windowpane", musician_id: musician.id, disc_id: disc.id)
70
- # form.validate("title" => "Windowpane", "musician_id" => musician.id, "disc" => disc)
71
- # refute_empty form.errors[:title]
72
- # end
73
-
74
- # # nested object taken.
75
- # it "is valid when musician name is unique" do
76
- # form.validate("musician" => {"name" => "Paul Gilbert"}, "title" => "The Gargoyle", "created_at" => "November 6, 1966").must_equal true
77
- # end
78
-
79
- # it "is invalid and shows error when taken" do
80
- # Tune.delete_all
81
- # Musician.create(:name => "Racer X")
82
-
83
- # form.validate("musician" => {"name" => "Racer X"}, "title" => "Ghost Inside My Skin").must_equal false
84
- # form.errors.messages.must_equal({:"musician.name"=>["is already taken"], :created_at => ["can't be blank"]})
85
- # end
86
-
87
- # it "works with Composition" do
88
- # form = Class.new(Reform::Form) do
89
- # include Reform::Form::Mongoid
90
- # include Reform::Form::Composition
91
-
92
- # property :name, :on => :musician
93
- # validates_uniqueness_of :name
94
- # end.new(:musician => Musician.new)
95
-
96
- # Musician.create(:name => "Bad Religion")
97
- # form.validate("name" => "Bad Religion").must_equal false
98
- # end
99
-
100
- # describe "#save" do
101
- # # TODO: test 1-n?
102
- # it "calls model.save" do
103
- # Musician.delete_all
104
- # form.validate("musician" => {"name" => "Bad Religion"}, "title" => "Ghost Inside My Skin")
105
- # form.save
106
- # Musician.where(:name => "Bad Religion").size.must_equal 1
107
- # end
108
-
109
- # it "doesn't call model.save when block is given" do
110
- # Musician.delete_all
111
- # form.validate("name" => "Bad Religion")
112
- # form.save {}
113
- # Musician.where(:name => "Bad Religion").size.must_equal 0
114
- # end
115
- # end
116
- # end
1
+ require 'test_helper'
2
+ def mongoid_present?
3
+ require 'mongoid'
4
+ Mongoid.configure do |config|
5
+ config.connect_to("reform-mongoid-test")
6
+ end
7
+ true
8
+ rescue
9
+ false
10
+ end
11
+
12
+ if mongoid_present?
13
+ require 'reform/mongoid'
14
+
15
+ class Disc
16
+ include Mongoid::Document
17
+ field :title, type: String
18
+ has_many :tunes
19
+ has_and_belongs_to_many :musicians
20
+ end
21
+
22
+ class Musician
23
+ include Mongoid::Document
24
+ field :name, type: String
25
+ end
26
+
27
+ class Tune
28
+ include Mongoid::Document
29
+ include Mongoid::Timestamps
30
+ field :title, type: String
31
+ belongs_to :disc
32
+ belongs_to :musician
33
+ end
34
+
35
+ class MongoidTest < MiniTest::Spec
36
+ class TuneForm < Reform::Form
37
+ include Reform::Form::Mongoid
38
+ model :tune
39
+
40
+ property :title
41
+ property :created_at
42
+
43
+ validates_uniqueness_of :title, scope: [:disc_id, :musician_id]
44
+ validates :created_at, :presence => true # have another property to test if we mix up.
45
+
46
+ property :musician do
47
+ property :name
48
+ validates_uniqueness_of :name # this currently also tests if Form::AR is included as a feature.
49
+ end
50
+ end
51
+
52
+ let(:disc) { Disc.create(:title => "Damnation") }
53
+ let(:musician) { Musician.create(:name => "Opeth") }
54
+ let(:form) { TuneForm.new(Tune.new(:musician => Musician.new)) }
55
+
56
+ it { form.class.i18n_scope.must_equal :mongoid }
57
+
58
+ it "allows accessing the database" do
59
+ end
60
+
61
+ # uniqueness
62
+ it "has no errors on title when title is unique for the same musician and disc" do
63
+ form.validate("title" => "The Gargoyle", "musician_id" => musician.id, "disc" => disc.id, "created_at" => "November 6, 1966")
64
+ assert_empty form.errors[:title]
65
+ end
66
+
67
+ it "has errors on title when title is taken for the same musician and disc" do
68
+ skip "replace ActiveModel::Validations with our own, working and reusable gem."
69
+ Tune.create(title: "Windowpane", musician_id: musician.id, disc_id: disc.id)
70
+ form.validate("title" => "Windowpane", "musician_id" => musician.id, "disc" => disc)
71
+ refute_empty form.errors[:title]
72
+ end
73
+
74
+ # nested object taken.
75
+ it "is valid when musician name is unique" do
76
+ form.validate("musician" => {"name" => "Paul Gilbert"}, "title" => "The Gargoyle", "created_at" => "November 6, 1966").must_equal true
77
+ end
78
+
79
+ it "is invalid and shows error when taken" do
80
+ Tune.delete_all
81
+ Musician.create(:name => "Racer X")
82
+
83
+ form.validate("musician" => {"name" => "Racer X"}, "title" => "Ghost Inside My Skin").must_equal false
84
+ form.errors.messages.must_equal({:"musician.name"=>["is already taken"], :created_at => ["can't be blank"]})
85
+ end
86
+
87
+ it "works with Composition" do
88
+ form = Class.new(Reform::Form) do
89
+ include Reform::Form::Mongoid
90
+ include Reform::Form::Composition
91
+
92
+ property :name, :on => :musician
93
+ validates_uniqueness_of :name
94
+ end.new(:musician => Musician.new)
95
+
96
+ Musician.create(:name => "Bad Religion")
97
+ form.validate("name" => "Bad Religion").must_equal false
98
+ end
99
+
100
+ describe "#save" do
101
+ # TODO: test 1-n?
102
+ it "calls model.save" do
103
+ Musician.delete_all
104
+ form.validate("musician" => {"name" => "Bad Religion"}, "title" => "Ghost Inside My Skin")
105
+ form.save
106
+ Musician.where(:name => "Bad Religion").size.must_equal 1
107
+ end
108
+
109
+ it "doesn't call model.save when block is given" do
110
+ Musician.delete_all
111
+ form.validate("name" => "Bad Religion")
112
+ form.save {}
113
+ Musician.where(:name => "Bad Religion").size.must_equal 0
114
+ end
115
+ end
116
+ end
117
+
117
118
 
119
+ class PopulateWithActiveRecordTest < MiniTest::Spec
120
+ class DiscForm < Reform::Form
118
121
 
119
- # class PopulateWithActiveRecordTest < MiniTest::Spec
120
- # class DiscForm < Reform::Form
122
+ property :title
121
123
 
122
- # property :title
124
+ collection :tunes, :populate_if_empty => Tune do
125
+ property :title
126
+ end
127
+ end
123
128
 
124
- # collection :tunes, :populate_if_empty => Tune do
125
- # property :title
126
- # end
127
- # end
129
+ let (:disc) { Disc.new(:tunes => []) }
130
+ it do
131
+ form = DiscForm.new(disc)
128
132
 
129
- # let (:disc) { Disc.new(:tunes => []) }
130
- # it do
131
- # form = DiscForm.new(disc)
133
+ form.validate("tunes" => [{"title" => "Straight From The Jacket"}])
132
134
 
133
- # form.validate("tunes" => [{"title" => "Straight From The Jacket"}])
135
+ # form populated.
136
+ form.tunes.size.must_equal 1
137
+ form.tunes[0].model.must_be_kind_of Tune
134
138
 
135
- # # form populated.
136
- # form.tunes.size.must_equal 1
137
- # form.tunes[0].model.must_be_kind_of Tune
139
+ # model NOT populated.
140
+ disc.tunes.must_equal []
138
141
 
139
- # # model NOT populated.
140
- # disc.tunes.must_equal []
141
142
 
143
+ form.sync
142
144
 
143
- # form.sync
145
+ # form populated.
146
+ form.tunes.size.must_equal 1
147
+ form.tunes[0].model.must_be_kind_of Tune
144
148
 
145
- # # form populated.
146
- # form.tunes.size.must_equal 1
147
- # form.tunes[0].model.must_be_kind_of Tune
149
+ # model also populated.
150
+ tune = disc.tunes[0]
151
+ disc.tunes.must_equal [tune]
152
+ tune.title.must_equal "Straight From The Jacket"
148
153
 
149
- # # model also populated.
150
- # tune = disc.tunes[0]
151
- # disc.tunes.must_equal [tune]
152
- # tune.title.must_equal "Straight From The Jacket"
153
154
 
155
+ # if ActiveRecord::VERSION::STRING !~ /^3.0/
156
+ # # saving saves association.
157
+ # form.save
158
+ #
159
+ # disc.reload
160
+ # tune = disc.tunes[0]
161
+ # disc.tunes.must_equal [tune]
162
+ # tune.title.must_equal "Straight From The Jacket"
163
+ # end
164
+ end
154
165
 
155
- # # if ActiveRecord::VERSION::STRING !~ /^3.0/
156
- # # # saving saves association.
157
- # # form.save
158
- # #
159
- # # disc.reload
160
- # # tune = disc.tunes[0]
161
- # # disc.tunes.must_equal [tune]
162
- # # tune.title.must_equal "Straight From The Jacket"
163
- # # end
164
- # end
165
166
 
167
+ describe "modifying 1., adding 2." do
168
+ let (:tune) { Tune.new(:title => "Part 2") }
169
+ let (:disc) { Disc.create.tap { |a| a.tunes << tune } }
166
170
 
167
- # describe "modifying 1., adding 2." do
168
- # let (:tune) { Tune.new(:title => "Part 2") }
169
- # let (:disc) { Disc.create.tap { |a| a.tunes << tune } }
171
+ it do
172
+ form = DiscForm.new(disc)
170
173
 
171
- # it do
172
- # form = DiscForm.new(disc)
174
+ id = disc.tunes[0].id
175
+ disc.tunes[0].persisted?.must_equal true
176
+ assert id.to_s.size > 0
173
177
 
174
- # id = disc.tunes[0].id
175
- # assert id > 0
178
+ form.validate("tunes" => [{"title" => "Part Two"}, {"title" => "Check For A Pulse"}])
176
179
 
177
- # form.validate("tunes" => [{"title" => "Part Two"}, {"title" => "Check For A Pulse"}])
180
+ # form populated.
181
+ form.tunes.size.must_equal 2
182
+ form.tunes[0].model.must_be_kind_of Tune
183
+ form.tunes[1].model.must_be_kind_of Tune
178
184
 
179
- # # form populated.
180
- # form.tunes.size.must_equal 2
181
- # form.tunes[0].model.must_be_kind_of Tune
182
- # form.tunes[1].model.must_be_kind_of Tune
185
+ # model NOT populated.
186
+ disc.tunes.must_equal [tune]
183
187
 
184
- # # model NOT populated.
185
- # disc.tunes.must_equal [tune]
186
188
 
189
+ form.sync
187
190
 
188
- # form.sync
191
+ # form populated.
192
+ form.tunes.size.must_equal 2
189
193
 
190
- # # form populated.
191
- # form.tunes.size.must_equal 2
194
+ # model also populated.
195
+ disc.tunes.size.must_equal 2
192
196
 
193
- # # model also populated.
194
- # disc.tunes.size.must_equal 2
197
+ # corrected title
198
+ disc.tunes[0].title.must_equal "Part Two"
199
+ # ..but same tune.
200
+ disc.tunes[0].id.must_equal id
195
201
 
196
- # # corrected title
197
- # disc.tunes[0].title.must_equal "Part Two"
198
- # # ..but same tune.
199
- # disc.tunes[0].id.must_equal id
202
+ # and a new tune.
203
+ disc.tunes[1].title.must_equal "Check For A Pulse"
204
+ disc.tunes[1].persisted?.must_equal true # TODO: with << strategy, this shouldn't be saved.
205
+ end
200
206
 
201
- # # and a new tune.
202
- # disc.tunes[1].title.must_equal "Check For A Pulse"
203
- # disc.tunes[1].persisted?.must_equal true # TODO: with << strategy, this shouldn't be saved.
204
- # end
207
+ describe 'using nested_models_attributes to modify nested collection' do
208
+ class ActiveModelDiscForm < Reform::Form
209
+ include Reform::Form::ActiveModel
210
+ include Reform::Form::ActiveModel::FormBuilderMethods
205
211
 
206
- # describe 'using nested_models_attributes to modify nested collection' do
207
- # class ActiveModelDiscForm < Reform::Form
208
- # include Reform::Form::ActiveModel
209
- # include Reform::Form::ActiveModel::FormBuilderMethods
212
+ property :title
210
213
 
211
- # property :title
214
+ collection :tunes, :populate_if_empty => Tune do
215
+ property :title
216
+ end
217
+ end
212
218
 
213
- # collection :tunes, :populate_if_empty => Tune do
214
- # property :title
215
- # end
216
- # end
219
+ let (:disc) { Disc.create(:title => 'Greatest Hits') }
220
+ let (:form) { ActiveModelDiscForm.new(disc) }
217
221
 
218
- # let (:disc) { Disc.create(:title => 'Greatest Hits') }
219
- # let (:form) { ActiveModelDiscForm.new(disc) }
222
+ it do
223
+ form.validate('tunes_attributes' => {'0' => {'title' => 'Tango'}})
220
224
 
221
- # it do
222
- # form.validate('tunes_attributes' => {'0' => {'title' => 'Tango'}})
225
+ # form populated.
226
+ form.tunes.size.must_equal 1
227
+ form.tunes[0].model.must_be_kind_of Tune
228
+ form.tunes[0].title.must_equal 'Tango'
223
229
 
224
- # # form populated.
225
- # form.tunes.size.must_equal 1
226
- # form.tunes[0].model.must_be_kind_of Tune
227
- # form.tunes[0].title.must_equal 'Tango'
230
+ # model NOT populated.
231
+ disc.tunes.must_equal []
228
232
 
229
- # # model NOT populated.
230
- # disc.tunes.must_equal []
233
+ form.save
231
234
 
232
- # form.save
235
+ # nested model persisted.
236
+ first_tune = disc.tunes[0]
237
+ first_tune.persisted?.must_equal true
238
+ assert first_tune.id.to_s.size > 0
233
239
 
234
- # # nested model persisted.
235
- # first_tune = disc.tunes[0]
236
- # assert first_tune.id > 0
240
+ # form populated.
241
+ form.tunes.size.must_equal 1
237
242
 
238
- # # form populated.
239
- # form.tunes.size.must_equal 1
243
+ # model also populated.
244
+ disc.tunes.size.must_equal 1
245
+ disc.tunes[0].title.must_equal 'Tango'
240
246
 
241
- # # model also populated.
242
- # disc.tunes.size.must_equal 1
243
- # disc.tunes[0].title.must_equal 'Tango'
247
+ form = ActiveModelDiscForm.new(disc)
248
+ form.validate('tunes_attributes' => {'0' => {'id' => first_tune.id, 'title' => 'Tango nuevo'}, '1' => {'title' => 'Waltz'}})
244
249
 
245
- # form = ActiveModelDiscForm.new(disc)
246
- # form.validate('tunes_attributes' => {'0' => {'id' => first_tune.id, 'title' => 'Tango nuevo'}, '1' => {'title' => 'Waltz'}})
250
+ # form populated.
251
+ form.tunes.size.must_equal 2
252
+ form.tunes[0].model.must_be_kind_of Tune
253
+ form.tunes[1].model.must_be_kind_of Tune
254
+ form.tunes[0].title.must_equal 'Tango nuevo'
255
+ form.tunes[1].title.must_equal 'Waltz'
247
256
 
248
- # # form populated.
249
- # form.tunes.size.must_equal 2
250
- # form.tunes[0].model.must_be_kind_of Tune
251
- # form.tunes[1].model.must_be_kind_of Tune
252
- # form.tunes[0].title.must_equal 'Tango nuevo'
253
- # form.tunes[1].title.must_equal 'Waltz'
257
+ # model NOT populated.
258
+ disc.tunes.size.must_equal 1
259
+ disc.tunes[0].title.must_equal 'Tango'
254
260
 
255
- # # model NOT populated.
256
- # disc.tunes.size.must_equal 1
257
- # disc.tunes[0].title.must_equal 'Tango'
261
+ form.save
258
262
 
259
- # form.save
263
+ # form populated.
264
+ form.tunes.size.must_equal 2
260
265
 
261
- # # form populated.
262
- # form.tunes.size.must_equal 2
266
+ # model also populated.
267
+ disc.tunes.size.must_equal 2
268
+ disc.tunes[0].id.must_equal first_tune.id
269
+ disc.tunes[0].persisted?.must_equal true
270
+ disc.tunes[1].persisted?.must_equal true
271
+ disc.tunes[0].title.must_equal 'Tango nuevo'
272
+ disc.tunes[1].title.must_equal 'Waltz'
273
+ end
274
+ end
275
+ end
263
276
 
264
- # # model also populated.
265
- # disc.tunes.size.must_equal 2
266
- # disc.tunes[0].id.must_equal first_tune.id
267
- # disc.tunes[0].persisted?.must_equal true
268
- # disc.tunes[1].persisted?.must_equal true
269
- # disc.tunes[0].title.must_equal 'Tango nuevo'
270
- # disc.tunes[1].title.must_equal 'Waltz'
271
- # end
272
- # end
273
- # end
277
+ # it do
278
+ # a=Disc.new
279
+ # a.tunes << Tune.new(title: "Old What's His Name") # Tune does not get persisted.
274
280
 
275
- # # it do
276
- # # a=Disc.new
277
- # # a.tunes << Tune.new(title: "Old What's His Name") # Tune does not get persisted.
281
+ # a.tunes[1] = Tune.new(title: "Permanent Rust")
278
282
 
279
- # # a.tunes[1] = Tune.new(title: "Permanent Rust")
283
+ # puts "@@@"
284
+ # puts a.tunes.inspect
280
285
 
281
- # # puts "@@@"
282
- # # puts a.tunes.inspect
286
+ # puts "---"
287
+ # a.save
288
+ # puts a.tunes.inspect
283
289
 
284
- # # puts "---"
285
- # # a.save
286
- # # puts a.tunes.inspect
290
+ # b = a.tunes.first
287
291
 
288
- # # b = a.tunes.first
292
+ # a.tunes = [Tune.new(title:"Biomag")]
293
+ # puts "\\\\"
294
+ # a.save
295
+ # a.reload
296
+ # puts a.tunes.inspect
297
+
298
+ # b.reload
299
+ # puts "#{b.inspect}, #{b.persisted?}"
289
300
 
290
- # # a.tunes = [Tune.new(title:"Biomag")]
291
- # # puts "\\\\"
292
- # # a.save
293
- # # a.reload
294
- # # puts a.tunes.inspect
295
301
 
296
- # # b.reload
297
- # # puts "#{b.inspect}, #{b.persisted?}"
302
+ # a.tunes = [a.tunes.first, Tune.new(title: "Count Down")]
303
+ # b = a.tunes.first
304
+ # puts ":::::"
305
+ # a.save
306
+ # a.reload
307
+ # puts a.tunes.inspect
298
308
 
299
-
300
- # # a.tunes = [a.tunes.first, Tune.new(title: "Count Down")]
301
- # # b = a.tunes.first
302
- # # puts ":::::"
303
- # # a.save
304
- # # a.reload
305
- # # puts a.tunes.inspect
306
-
307
- # # b.reload
308
- # # puts "#{b.inspect}, #{b.persisted?}"
309
- # # end
310
- # end
311
- # end
309
+ # b.reload
310
+ # puts "#{b.inspect}, #{b.persisted?}"
311
+ # end
312
+ end
313
+ 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: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-07-10 00:00:00.000000000 Z
12
+ date: 2015-07-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: disposable
@@ -196,7 +196,6 @@ files:
196
196
  - Rakefile
197
197
  - TODO.md
198
198
  - database.sqlite3
199
- - gemfiles/Gemfile.rails-3.0
200
199
  - gemfiles/Gemfile.rails-3.1
201
200
  - gemfiles/Gemfile.rails-3.2
202
201
  - gemfiles/Gemfile.rails-4.0
@@ -230,6 +229,7 @@ files:
230
229
  - lib/reform/schema.rb
231
230
  - lib/reform/version.rb
232
231
  - reform.gemspec
232
+ - test/active_model_custom_validation_translations_test.rb
233
233
  - test/active_model_test.rb
234
234
  - test/active_record_test.rb
235
235
  - test/benchmarking.rb
@@ -319,6 +319,7 @@ signing_key:
319
319
  specification_version: 4
320
320
  summary: Form object decoupled from models with validation, population and presentation.
321
321
  test_files:
322
+ - test/active_model_custom_validation_translations_test.rb
322
323
  - test/active_model_test.rb
323
324
  - test/active_record_test.rb
324
325
  - test/benchmarking.rb
@@ -1,7 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in reform.gemspec
4
- gemspec :path => '../'
5
-
6
- gem 'railties', '~> 3.0.11'
7
- gem 'activerecord', '~> 3.0.11'