ecoportal-api-v2 0.8.5 → 0.8.9
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/CHANGELOG.md +60 -25
- data/bin/console +1 -1
- data/ecoportal-api-v2.gemspec +5 -5
- data/lib/ecoportal/api-v2.rb +2 -2
- data/lib/ecoportal/api/common.v2.rb +8 -0
- data/lib/ecoportal/api/common/content.rb +1 -0
- data/lib/ecoportal/api/common/content/array_model.rb +8 -6
- data/lib/ecoportal/api/common/content/collection_model.rb +10 -4
- data/lib/ecoportal/api/common/content/double_model.rb +15 -4
- data/lib/ecoportal/api/common/content/hash_diff_patch.rb +31 -19
- data/lib/ecoportal/api/common/content/model_helpers.rb +36 -0
- data/lib/ecoportal/api/v2/page.rb +2 -0
- data/lib/ecoportal/api/v2/page/component.rb +33 -3
- data/lib/ecoportal/api/v2/page/component/action.rb +13 -5
- data/lib/ecoportal/api/v2/page/component/action_field.rb +37 -2
- data/lib/ecoportal/api/v2/page/component/chart_field.rb +43 -5
- data/lib/ecoportal/api/v2/page/component/chart_field/benchmark.rb +30 -0
- data/lib/ecoportal/api/v2/page/component/chart_field/config.rb +23 -0
- data/lib/ecoportal/api/v2/page/component/chart_field/frequency.rb +3 -4
- data/lib/ecoportal/api/v2/page/component/chart_field/heatmap.rb +1 -3
- data/lib/ecoportal/api/v2/page/component/chart_field/indicator.rb +4 -5
- data/lib/ecoportal/api/v2/page/component/chart_field/multiseries.rb +3 -5
- data/lib/ecoportal/api/v2/page/component/chart_field/sankey.rb +1 -3
- data/lib/ecoportal/api/v2/page/component/chart_field/serie.rb +3 -4
- data/lib/ecoportal/api/v2/page/component/chart_field/series_config.rb +5 -7
- data/lib/ecoportal/api/v2/page/component/chart_fr_field.rb +7 -5
- data/lib/ecoportal/api/v2/page/component/checklist_field.rb +1 -1
- data/lib/ecoportal/api/v2/page/component/checklist_item.rb +3 -2
- data/lib/ecoportal/api/v2/page/component/date_field.rb +71 -4
- data/lib/ecoportal/api/v2/page/component/file.rb +3 -2
- data/lib/ecoportal/api/v2/page/component/gauge_field.rb +2 -2
- data/lib/ecoportal/api/v2/page/component/geo_coordinates.rb +13 -0
- data/lib/ecoportal/api/v2/page/component/geo_field.rb +4 -1
- data/lib/ecoportal/api/v2/page/component/images_field.rb +57 -1
- data/lib/ecoportal/api/v2/page/component/people_field.rb +104 -6
- data/lib/ecoportal/api/v2/page/component/plain_text_field.rb +34 -2
- data/lib/ecoportal/api/v2/page/component/reference_field.rb +32 -3
- data/lib/ecoportal/api/v2/page/component/selection_field.rb +71 -4
- data/lib/ecoportal/api/v2/page/component/selection_option.rb +12 -2
- data/lib/ecoportal/api/v2/page/component/tag_field.rb +31 -1
- data/lib/ecoportal/api/v2/page/components.rb +8 -3
- data/lib/ecoportal/api/v2/page/permission_flags.rb +67 -0
- data/lib/ecoportal/api/v2/page/permit.rb +14 -0
- data/lib/ecoportal/api/v2/page/section.rb +65 -5
- data/lib/ecoportal/api/v2/page/sections.rb +64 -6
- data/lib/ecoportal/api/v2/page/stage.rb +11 -3
- data/lib/ecoportal/api/v2/page/stages.rb +7 -7
- data/lib/ecoportal/api/v2/pages/page_stage.rb +3 -3
- data/lib/ecoportal/api/v2_version.rb +5 -0
- metadata +16 -10
- data/lib/ecoportal/api/common.rb +0 -18
- data/lib/ecoportal/api/v2/version.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5833ea731a9d1360c346264d234ce9f95266db92a5480180a17f413459f196de
|
4
|
+
data.tar.gz: f3ef175580d2ab47c0ee7f51dc2731c0b42bd27ffa9f59600fb506d5cde38a4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52064ec37a32470e699f846ac1c6c57f8f535fb0be1d689a4f086836a47f9fb2805c0f84533842f5aaa4ee9e538c60e61c1569177ae16a015520c65248347174
|
7
|
+
data.tar.gz: 0f8cd291558cad37b5157dba7ffdea6670548952b6aa5b0c90b34820abd2693d8f484009265bbc4c8c83fb46684f2968e9a40d4a65563e0ffc6704cca30885d0
|
data/CHANGELOG.md
CHANGED
@@ -1,24 +1,79 @@
|
|
1
1
|
# Change Log
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
-
## [0.8.
|
4
|
+
## [0.8.9] - 2021-06-xx
|
5
5
|
|
6
6
|
### Added
|
7
|
+
- `Ecoportal::API::Common::Content::ModelHelpers`
|
8
|
+
- Starting with `#same_string?`, this lib aims to offer a full set of helper comparers.
|
9
|
+
- `Ecoportal::API::V2::Page::Components#get_by_id`
|
10
|
+
- In future changes, method `[]` might be overriding the method of the parent class `CollectionModel`.
|
11
|
+
- `Ecoportal::API::V2::Page::PermissionFlags` to offer support to `can_permission`, `subscribed`, etc.
|
12
|
+
- `Ecoportal::API::V2::Page::Section#add_component` super handy helper to add fields to sections.
|
13
|
+
- `Ecoportal::API::V2::Page::Component::PeopleField#delete` to remove people using their ids.
|
14
|
+
- `Ecoportal::API::V2::Page::Component::GeoField` **added** suport for `#coordinates`
|
15
|
+
- With embedded object `Ecoportal::API::V2::Page::Component::GeoCoordinates`
|
16
|
+
- `#configure` method, to all the `Component` types (but `ChartField` s)
|
17
|
+
- This method allows to quickly set field properties.
|
18
|
+
- `Ecoportal::API::V2::Page::Sections#between`, aiming to obtain sections between two other ones
|
19
|
+
|
20
|
+
|
7
21
|
### Changed
|
8
|
-
|
22
|
+
- `Ecoportal::API::V2::Page::Section` real support for `split` sections (right vs left)
|
23
|
+
- This is actually a **FIX**
|
24
|
+
- `Ecoportal::API::V2::Page::Component::DateField#create_event`
|
25
|
+
- Now it switches to _allow future dates_
|
26
|
+
- `Ecoportal::API::V2::Page::Component::SelectionField#add_option`, the `name` parameter is now optional
|
27
|
+
- This change aims to make it consistent with the back-end.
|
28
|
+
- To its actual `Boolean` type some properties
|
29
|
+
- All `Component` types
|
9
30
|
|
31
|
+
### Fixed
|
32
|
+
- `Ecoportal::API::Common::Content::HashDiffPatch` did not support `Hash` values without `id` or `patch_ver`
|
33
|
+
- This fix should allow them to flow to the update
|
34
|
+
- `Ecoportal::API::V2::Page::Component::ChartField` did not have `doc` for `mode` based configuration
|
35
|
+
- `Ecoportal::API::Common::Content::ArrayModel#insert_one`
|
36
|
+
- When `pos`, `before` & `after` were `nil` it was failing to attach the element.
|
37
|
+
- `Ecoportal::API::V2::Page::Sections#add` was not adding in the correct order
|
38
|
+
- `Ecoportal::API::V2::Page::Section.new_doc` was unnecessarily giving `9999` as default weight
|
10
39
|
|
11
|
-
## [0.8.
|
40
|
+
## [0.8.8] - 2021-08-03
|
12
41
|
|
13
42
|
### Added
|
43
|
+
- `Ecoportal::API::V2::Page::Component::ChartField::Benchmark`
|
44
|
+
- Support to convert selection options between numeric and text type.
|
45
|
+
- Add `Permit` object to `Page` and `Stage`
|
46
|
+
|
14
47
|
### Changed
|
15
|
-
-
|
48
|
+
- Removed `Stages.ordered_stages`: detected bug with Enumerable iteration
|
49
|
+
|
50
|
+
|
51
|
+
## [0.8.7] - 2021-05-25
|
52
|
+
|
53
|
+
### Changed
|
54
|
+
- Upgrade `ecoportal-api` gem
|
16
55
|
|
17
56
|
### Fixed
|
57
|
+
- Requiring `api/common` from 2 different ends
|
18
58
|
|
19
|
-
## [0.8.
|
59
|
+
## [0.8.6] - 2021-02-23
|
20
60
|
|
21
61
|
### Added
|
62
|
+
- `Ecoportal::API::V2::Page::Component::SelectionField` added methods `#numeric!` `#text!`
|
63
|
+
|
64
|
+
## [0.8.5] - 2021-02-22
|
65
|
+
|
66
|
+
### Changed
|
67
|
+
- upgrade
|
68
|
+
|
69
|
+
|
70
|
+
## [0.8.4] - 2021-02-22
|
71
|
+
|
72
|
+
### Changed
|
73
|
+
- roll back `ecoportal-api` dependency
|
74
|
+
|
75
|
+
## [0.8.3] - 2021-02-22
|
76
|
+
|
22
77
|
### Changed
|
23
78
|
- updated `rspec` for expected patch data on `delete` operation.
|
24
79
|
|
@@ -27,23 +82,16 @@ All notable changes to this project will be documented in this file.
|
|
27
82
|
|
28
83
|
## [0.8.2] - 2021-02-21
|
29
84
|
|
30
|
-
### Added
|
31
85
|
### Changed
|
32
86
|
- some necessary changes for the new gem to be active
|
33
87
|
|
34
|
-
### Fixed
|
35
|
-
|
36
88
|
## [0.8.1] - 2021-02-21
|
37
89
|
|
38
|
-
### Added
|
39
90
|
### Changed
|
40
91
|
- renamed parameters (backwards incompatible change):
|
41
92
|
- `Ecoportal::API::V2::Pages::Stages` methods `#get` and `#update`
|
42
93
|
- updated `Ecoportal::API::V2::Pages#` accordingly
|
43
94
|
|
44
|
-
### Fixed
|
45
|
-
|
46
|
-
|
47
95
|
## MOVED TO GEM `ecoportal-api-v2` ##
|
48
96
|
|
49
97
|
## [0.7.5] - 2021-02-21
|
@@ -137,42 +185,29 @@ All notable changes to this project will be documented in this file.
|
|
137
185
|
- automatic key builder
|
138
186
|
- helper: `Ecoportal::API::V2::v2key` method
|
139
187
|
- `user_key:` and `org_key:` as constructor methods for `Ecoportal::API::V2`
|
140
|
-
### Changed
|
141
|
-
### Fixed
|
142
188
|
|
143
189
|
## [0.7.1] - 2020-10-07
|
144
190
|
|
145
|
-
### Added
|
146
191
|
### Changed
|
147
192
|
- updated dependencies
|
148
|
-
### Fixed
|
149
|
-
|
150
193
|
|
151
194
|
## [0.7.0] - 2020-09-10
|
152
195
|
|
153
|
-
### Added
|
154
196
|
### Changed
|
155
197
|
- updated dependencies
|
156
|
-
### Fixed
|
157
198
|
|
158
199
|
## [0.6.1] - 2020-07-11
|
159
200
|
|
160
201
|
### Added
|
161
202
|
- `Ecoportal::API::Common::Content::DoubleModel#pretty_print`
|
162
|
-
### Changed
|
163
|
-
### Fixed
|
164
203
|
|
165
204
|
## [0.6.0] - 2020-07-11
|
166
205
|
|
167
|
-
### Added
|
168
206
|
### Changed
|
169
207
|
- upgraded `ecoportal-api` gem
|
170
|
-
### Fixed
|
171
208
|
|
172
209
|
## [0.5.9] - 2020-07-02
|
173
210
|
|
174
211
|
### Added
|
175
212
|
- helper `Ecoportal::API::Common::Content::StringDigest#indexable_label`: to see the part of a label that gets indexed
|
176
213
|
- this `CHANGELOG.md` file
|
177
|
-
### Changed
|
178
|
-
### Fixed
|
data/bin/console
CHANGED
data/ecoportal-api-v2.gemspec
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
|
2
2
|
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require "ecoportal/api/
|
4
|
+
require "ecoportal/api/v2_version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "ecoportal-api-v2"
|
8
|
-
spec.version = Ecoportal::API::
|
8
|
+
spec.version = Ecoportal::API::GEM2_VERSION
|
9
9
|
spec.authors = ["Oscar Segura"]
|
10
10
|
spec.email = ["rien@ecoportal.co.nz", "oscar@ecoportal.co.nz", "bozydar@ecoportal.co.nz"]
|
11
11
|
|
@@ -22,12 +22,12 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
|
-
spec.add_development_dependency "bundler", ">= 2.2.
|
25
|
+
spec.add_development_dependency "bundler", ">= 2.2.17", "< 2.3"
|
26
26
|
spec.add_development_dependency "rspec", ">= 3.10.0", "< 3.11"
|
27
27
|
spec.add_development_dependency "rake", ">= 13.0.3", "< 13.1"
|
28
28
|
spec.add_development_dependency "yard", ">= 0.9.26", "< 0.10"
|
29
29
|
spec.add_development_dependency "redcarpet", ">= 3.5.1", "< 3.6"
|
30
|
-
spec.add_development_dependency "pry" , "
|
30
|
+
spec.add_development_dependency "pry" , ">= 0.14"
|
31
31
|
|
32
|
-
spec.add_dependency 'ecoportal-api', '>= 0.8.
|
32
|
+
spec.add_dependency 'ecoportal-api', '>= 0.8.3', '< 0.9'
|
33
33
|
end
|
data/lib/ecoportal/api-v2.rb
CHANGED
@@ -9,6 +9,7 @@ end
|
|
9
9
|
|
10
10
|
require 'ecoportal/api/common/content/class_helpers'
|
11
11
|
require 'ecoportal/api/common/content/string_digest'
|
12
|
+
require 'ecoportal/api/common/content/model_helpers'
|
12
13
|
require 'ecoportal/api/common/content/double_model'
|
13
14
|
require 'ecoportal/api/common/content/array_model'
|
14
15
|
require 'ecoportal/api/common/content/collection_model'
|
@@ -3,7 +3,8 @@ module Ecoportal
|
|
3
3
|
module Common
|
4
4
|
module Content
|
5
5
|
# Class to handle a plain Array embedded in a Hashed model.
|
6
|
-
# @note
|
6
|
+
# @note
|
7
|
+
# - Its purpose is to handle an Array of basic objects (i.e. `Date`, `String`, `Number`)
|
7
8
|
class ArrayModel < Content::DoubleModel
|
8
9
|
class TypeMismatchedComparison < Exception
|
9
10
|
def initialize (this: nil, that: msg = "Trying to compare objects with different behavior.")
|
@@ -222,15 +223,16 @@ module Ecoportal
|
|
222
223
|
def insert_one(value, pos: NOT_USED, before: NOT_USED, after: NOT_USED)
|
223
224
|
i = index(value)
|
224
225
|
return i if (i && uniq?)
|
225
|
-
|
226
226
|
pos = case
|
227
227
|
when used_param?(pos)
|
228
|
-
pos
|
228
|
+
pos || length
|
229
229
|
when used_param?(before)
|
230
|
-
index(before)
|
230
|
+
before ? index(before) : length
|
231
231
|
when used_param?(after)
|
232
|
-
if
|
233
|
-
i + 1
|
232
|
+
if after
|
233
|
+
if i = index(after) then i + 1 end
|
234
|
+
else
|
235
|
+
length
|
234
236
|
end
|
235
237
|
else
|
236
238
|
length
|
@@ -2,6 +2,9 @@ module Ecoportal
|
|
2
2
|
module API
|
3
3
|
module Common
|
4
4
|
module Content
|
5
|
+
# CollectionModel aims to deal with Arrays of actual objects.
|
6
|
+
# @note to be able to refer to the correct element of the Collection,
|
7
|
+
# it is required that those elements have a unique `key` that allows to identify them
|
5
8
|
class CollectionModel < Content::DoubleModel
|
6
9
|
|
7
10
|
class << self
|
@@ -167,6 +170,7 @@ module Ecoportal
|
|
167
170
|
end
|
168
171
|
end
|
169
172
|
|
173
|
+
# Deletes `value` from this `CollectionModel` instance
|
170
174
|
def delete!(value)
|
171
175
|
unless value.is_a?(Hash) || value.is_a?(Content::DoubleModel)
|
172
176
|
raise "'Content::DoubleModel' or 'Hash' doc required"
|
@@ -186,7 +190,7 @@ module Ecoportal
|
|
186
190
|
variables_remove!
|
187
191
|
end
|
188
192
|
|
189
|
-
# Gets the `key` of the object
|
193
|
+
# Gets the `key` of the object `value`
|
190
194
|
def get_key(value)
|
191
195
|
case value
|
192
196
|
when Content::DoubleModel
|
@@ -235,10 +239,13 @@ module Ecoportal
|
|
235
239
|
super
|
236
240
|
end
|
237
241
|
|
242
|
+
# Deletes `value` from `doc` (here referred as `_doc_items`)
|
243
|
+
# @return [Object] the element deleted from `doc`
|
238
244
|
def _doc_delete(value)
|
239
245
|
if current_pos = _doc_key(value)
|
240
|
-
_doc_items.delete_at(current_pos)
|
241
|
-
|
246
|
+
_doc_items.delete_at(current_pos).tap do |deleted|
|
247
|
+
on_change
|
248
|
+
end
|
242
249
|
end
|
243
250
|
end
|
244
251
|
|
@@ -250,7 +257,6 @@ module Ecoportal
|
|
250
257
|
when used_param?(before)
|
251
258
|
_doc_key(before)
|
252
259
|
when used_param?(after)
|
253
|
-
#puts "to add after #{after.id}"
|
254
260
|
if i = _doc_key(after)
|
255
261
|
i + 1
|
256
262
|
end
|
@@ -10,6 +10,7 @@ module Ecoportal
|
|
10
10
|
class DoubleModel < Common::BaseModel
|
11
11
|
NOT_USED = Common::Content::ClassHelpers::NOT_USED
|
12
12
|
extend Common::Content::ClassHelpers
|
13
|
+
include Common::Content::ModelHelpers
|
13
14
|
|
14
15
|
class UnlinkedModel < Exception
|
15
16
|
def initialize (msg = "Something went wrong when linking the document.", from: nil, key: nil)
|
@@ -109,6 +110,16 @@ module Ecoportal
|
|
109
110
|
self
|
110
111
|
end
|
111
112
|
|
113
|
+
# To link as a `Boolean` to a subjacent `Hash` model property
|
114
|
+
# @param read_only [Boolean] should it only define the reader?
|
115
|
+
def passboolean(*methods, read_only: false)
|
116
|
+
pass_reader(*methods) {|value| value}
|
117
|
+
unless read_only
|
118
|
+
pass_writer(*methods) {|value| !!value}
|
119
|
+
end
|
120
|
+
self
|
121
|
+
end
|
122
|
+
|
112
123
|
# To link as plain `Array` to a subjacent `Hash` model property
|
113
124
|
# @param order_matters [Boolean] does the order matter
|
114
125
|
# @param uniq [Boolean] should it contain unique elements
|
@@ -151,7 +162,7 @@ module Ecoportal
|
|
151
162
|
else
|
152
163
|
raise "You should either specify the 'klass' of the elements or the 'enum_class'"
|
153
164
|
end
|
154
|
-
embed(method, key: key, multiple: true, klass: eclass)
|
165
|
+
embed(method, key: key, multiple: true, klass: eclass)
|
155
166
|
end
|
156
167
|
|
157
168
|
private
|
@@ -258,10 +269,10 @@ module Ecoportal
|
|
258
269
|
|
259
270
|
def reset!(key = nil)
|
260
271
|
if key
|
261
|
-
keys = [].
|
272
|
+
keys = [key].flatten.compact
|
262
273
|
odoc = original_doc.dig(*keys)
|
263
|
-
|
264
|
-
|
274
|
+
odoc = odoc && JSON.parse(odoc.to_json)
|
275
|
+
dig_set(doc, keys, odoc)
|
265
276
|
else
|
266
277
|
replace_doc(JSON.parse(original_doc.to_json))
|
267
278
|
end
|
@@ -85,31 +85,43 @@ module Ecoportal
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def patch_delete(b)
|
88
|
-
return NO_CHANGES unless b.is_a?(Hash)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
88
|
+
return NO_CHANGES unless b.is_a?(Hash)
|
89
|
+
if id = get_id(b, exception: false)
|
90
|
+
{
|
91
|
+
"id" => id,
|
92
|
+
"operation" => "deleted",
|
93
|
+
"data" => patch_data(b, delete: true)
|
94
|
+
}
|
95
|
+
else
|
96
|
+
nil
|
97
|
+
end
|
94
98
|
end
|
95
99
|
|
96
100
|
def patch_new(a)
|
97
|
-
return NO_CHANGES unless a.is_a?(Hash)
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
return NO_CHANGES unless a.is_a?(Hash)
|
102
|
+
if id = get_id(a, exception: false)
|
103
|
+
{
|
104
|
+
"id" => id,
|
105
|
+
"operation" => "new",
|
106
|
+
"data" => patch_data(a)
|
107
|
+
}
|
108
|
+
else
|
109
|
+
a
|
110
|
+
end
|
103
111
|
end
|
104
112
|
|
105
113
|
def patch_update(a, b)
|
106
|
-
return NO_CHANGES unless a.is_a?(Hash)
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
114
|
+
return NO_CHANGES unless a.is_a?(Hash)
|
115
|
+
if id = get_id(a, exception: false)
|
116
|
+
{
|
117
|
+
"id" => id,
|
118
|
+
"operation" => "changed",
|
119
|
+
"data" => patch_data(a, b)
|
120
|
+
}.tap do |update_hash|
|
121
|
+
return nil unless update_hash["data"] != NO_CHANGES
|
122
|
+
end
|
123
|
+
else
|
124
|
+
a
|
113
125
|
end
|
114
126
|
end
|
115
127
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Ecoportal
|
2
|
+
module API
|
3
|
+
module Common
|
4
|
+
module Content
|
5
|
+
module ModelHelpers
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
# Offers multiple ways to compare two strings
|
10
|
+
def same_string?(value1, value2, exact: false)
|
11
|
+
case
|
12
|
+
when value1.is_a?(String) && value2.is_a?(String)
|
13
|
+
if exact
|
14
|
+
value1 == value2
|
15
|
+
else
|
16
|
+
value1.to_s.strip.downcase == value2.to_s.strip.downcase
|
17
|
+
end
|
18
|
+
when value1.is_a?(Regexp) && value2.is_a?(String)
|
19
|
+
value2 =~ value1
|
20
|
+
when value1.is_a?(String) && value2.is_a?(Regexp)
|
21
|
+
value1 =~ value2
|
22
|
+
else
|
23
|
+
value1 == value2
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def hash_except(hash, *keys)
|
28
|
+
keys.each {|key| hash.delete(key)}
|
29
|
+
hash
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|