gourami 1.3.0 → 1.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9aeeb89759c11dd7f9559824ccfd42bc6ab7755aa2d60f11b8a38e5b0db08902
4
- data.tar.gz: 80c1968c495c2cff9277b4bd51c0340bd8381874dc864d53dab711091f61443a
3
+ metadata.gz: 471278c6d8c858485bdec0d124139f3ccd4251eedbad1573059dcf4519ec9b0a
4
+ data.tar.gz: 2e62de42a3eb36e05cd247bed62ccb7f7bfecb796318a1b0c5dfeb79ce6b28bf
5
5
  SHA512:
6
- metadata.gz: 97af9a59317e79d499c95b7b05f31a5089e9f56c7b7970818c22b36482de075f646f212b12e41ad4b53d9be1e967c34b08b34e55c46a90e033151f46416208dc
7
- data.tar.gz: 48979f3194878e519431c3a46deb3da5eea9dc624731483f89e8006370d84c30027445b4ac6b31f0ca91b1d669539ad79edf988c51a2d8b2f56f7877b1659cdd
6
+ metadata.gz: '09d6304054c99cbf3587005dfc38c8fef568dff2339cfc1ae41642bacbf4c80da1a91c54bc435b90253ac01d7c72927f516b945838db698d33df7250bb686499'
7
+ data.tar.gz: e33e55074af37d7776329feb8a491687ab43dea237d5ce96cd4dd9ff1d80f6a580b43b6015021c69a9444d48f788bcd1bd16c512f07da4f6377f3a19d0682ea8
@@ -0,0 +1 @@
1
+ 2.5.3
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Gourami
2
2
 
3
+ [![Codeship Status for Vydia/gourami](https://app.codeship.com/projects/316bc070-f431-0136-4713-52c1ec7c066f/status?branch=master)](https://app.codeship.com/projects/320673)
4
+
3
5
  Keep your Routes, Controllers and Models thin with Plain Old Ruby Objects (PORO).
4
6
 
5
7
  ## Installation
@@ -12,7 +14,7 @@ gem 'gourami'
12
14
 
13
15
  And then execute:
14
16
 
15
- $ bundle
17
+ $ bundle install
16
18
 
17
19
  Or install it yourself as:
18
20
 
@@ -20,10 +22,10 @@ Or install it yourself as:
20
22
 
21
23
  ## Usage
22
24
 
23
- ### A Typical Gourami::Form will
25
+ ### A Typical `Gourami::Form` will
24
26
 
25
- - Define some attributes
26
- - Validate user input
27
+ - Define attributes (inputs & outputs)
28
+ - Validate input
27
29
  - Perform an action
28
30
 
29
31
  ```ruby
@@ -173,6 +175,56 @@ class UpdateFishBowl < CreateFishBowl
173
175
  end
174
176
  ```
175
177
 
178
+ #### Configure default attribute options
179
+
180
+ The following examples will result in all `:string` attributes getting the options `:strip` and `:upcase` set to `true`.
181
+
182
+ Set global defaults:
183
+
184
+ ```ruby
185
+ Gourami::Form.set_default_attribute_options(:string, upcase: true)
186
+
187
+ # Make sure to define CreateFishBowl and other forms AFTER setting default options.
188
+ class CreateFishBowl < Gourami::Form
189
+ attribute(:name, type: :string)
190
+ end
191
+
192
+ form = CreateFishBowl.new(name: "Snake Gyllenhaal")
193
+ form.name # => "SNAKE GYLLENHAAL"
194
+ ```
195
+
196
+ Instead of global defaults, you can also apply defaults to certain form classes.
197
+
198
+ Just as `attributes` are inherited by subclasses, so are `default_attribute_options`.
199
+
200
+ Set local defaults:
201
+
202
+ ```ruby
203
+ class ScreamingForm < Gourami::Form
204
+ set_default_attribute_options(:string, upcase: true)
205
+ end
206
+
207
+ class CreateScreamingFish < ScreamingForm
208
+ attribute(:name, type: :string)
209
+ end
210
+
211
+ class UpdateScreamingFish < CreateScreamingFish; end
212
+
213
+ create_form = CreateScreamingFish.new(name: "Snake Gyllenhaal")
214
+ create_form.name # => "SNAKE GYLLENHAAL"
215
+
216
+ update_form = UpdateScreamingFish.new(name: "Snake Gyllenhaal")
217
+ update_form.name # => "SNAKE GYLLENHAAL"
218
+
219
+ # Other Gourami::Forms are unaffected
220
+ class RegularForm < Gourami::Form
221
+ attribute(:name, type: :string)
222
+ end
223
+
224
+ regular_form = RegularForm.new(name: "Snake Gyllenhaal")
225
+ regular_form.name # => "Snake Gyllenhaal"
226
+ ```
227
+
176
228
  #### Extensions / Plugins
177
229
 
178
230
  ##### Gourami::Extensions::Changes
@@ -250,7 +302,7 @@ end
250
302
 
251
303
  ## Development
252
304
 
253
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
305
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests, or `rake test:watch` to automatically rerun the tests when you make code changes. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
254
306
 
255
307
  To install this gem onto your local machine, run `bundle exec rake install`.
256
308
 
@@ -9,6 +9,7 @@ module Gourami
9
9
  def inherited(klass)
10
10
  super(klass)
11
11
  klass.instance_variable_set(:@attributes, attributes.dup)
12
+ klass.instance_variable_set(:@default_attribute_options, default_attribute_options.dup)
12
13
  end
13
14
 
14
15
  # Define an attribute for the form.
@@ -25,15 +26,17 @@ module Gourami
25
26
  options = options.dup
26
27
  options[:default] = default_block if block_given?
27
28
 
29
+ options_with_defaults = merge_default_attribute_options(options)
30
+
28
31
  mixin = Module.new do |mixin|
29
- unless options[:skip_reader]
30
- if !base.attributes.key?(name) && base.instance_methods.include?(name) && !options[:override_reader]
32
+ unless options_with_defaults[:skip_reader]
33
+ if !base.attributes.key?(name) && base.instance_methods.include?(name) && !options_with_defaults[:override_reader]
31
34
  raise AttributeNameConflictError, "#{name} is already a method. To use the existing method, use `:skip_reader => true` option. To override the existing method, use `:override_reader => true` option."
32
35
  end
33
36
 
34
37
  mixin.send(:define_method, :"#{name}") do
35
38
  value = instance_variable_get(:"@#{name}")
36
- default = options[:default]
39
+ default = options_with_defaults[:default]
37
40
 
38
41
  if value.nil? && default
39
42
  default.respond_to?(:call) ? instance_exec(&default) : default
@@ -51,7 +54,7 @@ module Gourami
51
54
 
52
55
  # Define internal setter.
53
56
  mixin.send(:define_method, :"_#{name}=") do |value|
54
- instance_variable_set(:"@#{name}", setter_filter(name, value, options))
57
+ instance_variable_set(:"@#{name}", setter_filter(name, value, self.class.merge_default_attribute_options(options)))
55
58
  end
56
59
  mixin.send(:private, :"_#{name}=")
57
60
 
@@ -90,6 +93,24 @@ module Gourami
90
93
  def attributes
91
94
  @attributes ||= {}
92
95
  end
96
+
97
+ # Useful if you want, for example, all type: :string attributes to use
98
+ # strip: true to remove whitespace padding.
99
+ def set_default_attribute_options(attr_type, options)
100
+ default_attribute_options[attr_type] = options
101
+ end
102
+
103
+ def default_attribute_options
104
+ @default_attribute_options ||= {}
105
+ end
106
+
107
+ def merge_default_attribute_options(options)
108
+ if options[:type]
109
+ default_attribute_options.fetch(options[:type], {}).merge(options)
110
+ else
111
+ options
112
+ end
113
+ end
93
114
  end
94
115
 
95
116
  # Extend ClassMethods into including class.
@@ -33,6 +33,9 @@ module Gourami
33
33
  end
34
34
 
35
35
  value = value.to_s.dup.force_encoding(Encoding::UTF_8)
36
+
37
+ # TODO: Instead of providing unconfigurable defaults like this, use
38
+ # set_default_attribute_options at the gem level or consumer level.
36
39
  value.strip! if options.fetch(:strip, true)
37
40
  value.upcase! if options.fetch(:upcase, false)
38
41
 
@@ -84,6 +87,9 @@ module Gourami
84
87
  element_type_options = {}
85
88
  end
86
89
 
90
+ element_type_options[:type] = element_type
91
+ element_type_options = self.class.merge_default_attribute_options(element_type_options) if self.class.respond_to?(:merge_default_attribute_options)
92
+
87
93
  coercer_method_name = :"coerce_#{element_type}"
88
94
 
89
95
  value.map do |array_element|
@@ -149,6 +155,9 @@ module Gourami
149
155
  value_type_options = {}
150
156
  end
151
157
 
158
+ value_type_options[:type] = value_type
159
+ value_type_options = self.class.merge_default_attribute_options(value_type_options) if self.class.respond_to?(:merge_default_attribute_options)
160
+
152
161
  value = send(:"coerce_#{value_type}", value, value_type_options) if value_type
153
162
 
154
163
  coerced_hash[key] = value
@@ -1,3 +1,3 @@
1
1
  module Gourami
2
- VERSION = "1.3.0".freeze
2
+ VERSION = "1.3.1".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gourami
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - TSMMark
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-09 00:00:00.000000000 Z
11
+ date: 2020-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -89,6 +89,7 @@ extensions: []
89
89
  extra_rdoc_files: []
90
90
  files:
91
91
  - ".gitignore"
92
+ - ".ruby-version"
92
93
  - ".travis.yml"
93
94
  - CODE_OF_CONDUCT.md
94
95
  - Gemfile
@@ -118,7 +119,7 @@ homepage: http://github.com/Vydia/gourami
118
119
  licenses:
119
120
  - MIT
120
121
  metadata: {}
121
- post_install_message:
122
+ post_install_message:
122
123
  rdoc_options: []
123
124
  require_paths:
124
125
  - lib
@@ -134,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
135
  version: '0'
135
136
  requirements: []
136
137
  rubygems_version: 3.0.4
137
- signing_key:
138
+ signing_key:
138
139
  specification_version: 4
139
140
  summary: Keep your Routes, Controllers and Models thin.
140
141
  test_files: []